time/src/POSIX/DateLinux.m3


Copyright (C) 1994, Digital Equipment Corp.

UNSAFE MODULE DateLinux EXPORTS Date;

IMPORT Thread, Time, Utime, TimePosix, M3toC;

VAR mu := NEW(Thread.Mutex);
Protect the static storage used by Utime.localtime and Utime.gmtime (see the localtime(3) manpage).

REVEAL TimeZone = BRANDED "Date.TimeZone" REF INTEGER;

CONST Unknown = "[Unknown zone]";

PROCEDURE FromTime(t: Time.T; z: TimeZone := NIL): T =
  VAR
    date : T;
    tv   : Utime.struct_timeval;
    tm   : Utime.struct_tm_star;
  BEGIN
    tv := TimePosix.ToUtime(t);
    LOCK mu DO
      IF (z = NIL) OR (z^ = 0)
        THEN tm := Utime.localtime(ADR(tv.tv_sec));
        ELSE tm := Utime.gmtime(ADR(tv.tv_sec));
      END;
      date.year    := tm.tm_year + 1900;
      date.month   := VAL(tm.tm_mon, Month);
      date.day     := tm.tm_mday;
      date.hour    := tm.tm_hour;
      date.minute  := tm.tm_min;
      date.second  := tm.tm_sec;
      date.weekDay := VAL(tm.tm_wday, WeekDay);

      IF tm.tm_isdst = 0 THEN
        date.offset := Utime.timezone;
        date.zone   := M3toC.CopyStoT (Utime.tzname[0]);
      ELSIF tm.tm_isdst > 0 AND Utime.daylight # 0 THEN
        date.offset := Utime.altzone;
        date.zone   := M3toC.CopyStoT (Utime.tzname[1]);
      ELSE
        date.offset := 0;
        date.zone   := Unknown;
      END;

    END;
    RETURN date;
  END FromTime;

PROCEDURE ToTime(READONLY d: T): Time.T RAISES {Error} =
  VAR
    tm: Utime.struct_tm;
    time: Utime.time_t;
    t: Time.T;
  BEGIN
    tm.tm_sec    := d.second;
    tm.tm_min    := d.minute;
    tm.tm_hour   := d.hour;
    tm.tm_mday   := d.day;
    tm.tm_mon    := ORD(d.month);
    tm.tm_year   := d.year - 1900;
    (* tm.tm_wday ignored *)
    tm.tm_isdst  := 0; (* tell mktime that DST is not in effect *)
    time := Utime.mktime(ADR(tm));
    IF time = -1 THEN RAISE Error END;
    t := FLOAT(time, LONGREAL);
    RETURN t;
  END ToTime;

BEGIN
  Local := NEW(TimeZone);  Local^ := 0;
  UTC   := NEW(TimeZone);  UTC^   := 1;
END DateLinux.

interface Utime is in: