sysclock.mod 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. IMPLEMENTATION MODULE SysClock;
  2. (* ISO 10514-1 clock interface, bound to the shim's time/clock calls.
  3. GetClock computes the UTC civil date from the Unix epoch seconds. *)
  4. PROCEDURE m2time() : LONGINT;
  5. EXTERNAL;
  6. PROCEDURE m2clock() : LONGINT;
  7. EXTERNAL;
  8. PROCEDURE Time() : LONGINT;
  9. BEGIN
  10. RETURN m2time()
  11. END Time;
  12. PROCEDURE Clock() : LONGINT;
  13. BEGIN
  14. RETURN m2clock()
  15. END Clock;
  16. PROCEDURE DaysToDate (days: INTEGER; VAR y, m, d: INTEGER);
  17. (* proleptic Gregorian civil date from days since 1970-01-01
  18. (Hinnant's algorithm; INTEGER is wide enough for the epoch range). *)
  19. VAR z, era, doe, yoe, doy, mp: INTEGER;
  20. BEGIN
  21. z := days + 719468;
  22. era := z DIV 146097;
  23. doe := z - era * 146097;
  24. yoe := (doe - doe DIV 1460 + doe DIV 36524 - doe DIV 146096) DIV 365;
  25. y := yoe + era * 400;
  26. doy := doe - (365 * yoe + yoe DIV 4 - yoe DIV 100);
  27. mp := (5 * doy + 2) DIV 153;
  28. d := doy - (153 * mp + 2) DIV 5 + 1;
  29. IF mp < 10 THEN m := mp + 3 ELSE m := mp - 9 END;
  30. IF m <= 2 THEN INC(y) END
  31. END DaysToDate;
  32. PROCEDURE CanGetClock () : BOOLEAN;
  33. BEGIN
  34. RETURN TRUE
  35. END CanGetClock;
  36. PROCEDURE CanSetClock () : BOOLEAN;
  37. BEGIN
  38. RETURN FALSE
  39. END CanSetClock;
  40. PROCEDURE IsValidDateTime (userData: DateTime) : BOOLEAN;
  41. BEGIN
  42. RETURN (userData.year <= 9999)
  43. AND (userData.month >= 1) AND (userData.month <= 12)
  44. AND (userData.day >= 1) AND (userData.day <= 31)
  45. AND (userData.hour <= 23)
  46. AND (userData.minute <= 59)
  47. AND (userData.second <= 59)
  48. AND (userData.fractions <= maxSecondParts)
  49. AND (userData.zone >= -780) AND (userData.zone <= 720)
  50. END IsValidDateTime;
  51. PROCEDURE GetClock (VAR userData: DateTime);
  52. VAR secs, days, sod, y, m, d, hh, mm, ss: INTEGER;
  53. BEGIN
  54. secs := INTEGER(Time());
  55. days := secs DIV 86400;
  56. sod := secs MOD 86400;
  57. IF sod < 0 THEN
  58. (* floor division for times before 1970 *)
  59. DEC(days); INC(sod, 86400)
  60. END;
  61. DaysToDate(days, y, m, d);
  62. hh := sod DIV 3600;
  63. mm := (sod MOD 3600) DIV 60;
  64. ss := sod MOD 60;
  65. userData.year := y;
  66. userData.month := m;
  67. userData.day := d;
  68. userData.hour := hh;
  69. userData.minute := mm;
  70. userData.second := ss;
  71. userData.fractions := 0;
  72. userData.zone := 0;
  73. userData.summerTimeFlag := FALSE
  74. END GetClock;
  75. PROCEDURE SetClock (userData: DateTime);
  76. BEGIN
  77. (* unsupported: CanSetClock is FALSE *)
  78. END SetClock;
  79. END SysClock.