logo

const class

sys::DateTime

sys::Obj
  sys::DateTime
   1  //
   2  // Copyright (c) 2006, Brian Frank and Andy Frank
   3  // Licensed under the Academic Free License version 3.0
   4  //
   5  // History:
   6  //   3 Jul 06  Brian Frank  Creation
   7  //
   8  
   9  **
  10  ** DateTime represents an absolute instance in time.  Fan time is
  11  ** normalized as nanosecond ticks since 1 Jan 2000 UTC with a
  12  ** supported range of 1901 to 2099.  Fan time does not support
  13  ** leap seconds (same as Java and UNIX).  An instance of DateTime
  14  ** also models the date and time of an absolute instance against
  15  ** a specific `TimeZone`.
  16  **
  17  @simple
  18  const final class DateTime
  19  {
  20  
  21  //////////////////////////////////////////////////////////////////////////
  22  // Constructor
  23  //////////////////////////////////////////////////////////////////////////
  24  
  25    **
  26    ** Return the current time using `TimeZone.current`.  The tolerance
  27    ** parameter specifies that you are willing to use a cached DateTime
  28    ** instance as long as (now - cached <= tolerance).  If tolerance is null,
  29    ** then this method always creates a new DateTime instance.  Using
  30    ** tolerance can increase performance and save memory.  The
  31    ** tolerance default is 250ms.
  32    **
  33    ** If you are using time to calculate relative time periods,
  34    ** then use `Duration.now` instead.  Duration is more efficient
  35    ** and won't cause you grief when the system clock is modified.
  36    **
  37    static DateTime now(Duration tolerance := 250ms)
  38  
  39    **
  40    ** Make for nanosecond ticks since 1 Jan 2000 GMT.  Throw
  41    ** ArgErr if ticks represent a year out of the range 1901
  42    ** to 2099.
  43    **
  44    static DateTime makeTicks(Int ticks, TimeZone tz := TimeZone.current)
  45  
  46    **
  47    ** Make for the specified date and time values:
  48    **  - year:  1901-2099
  49    **  - month: Month enumeration
  50    **  - day:   1-31
  51    **  - hour:  0-23
  52    **  - min:   0-59
  53    **  - sec:   0-59
  54    **  - ns:    0-999_999_999
  55    **  - tz:    time zone used to map date/time to ns ticks
  56    **
  57    ** Throw ArgErr is any of the parameters are out of range.
  58    **
  59    static DateTime make(Int year, Month month, Int day, Int hour, Int min, Int sec := 0, Int ns := 0, TimeZone tz := TimeZone.current)
  60  
  61    **
  62    ** Parse the string into a DateTime from the programmatic encoding
  63    ** defined by `toStr`.  If the string cannot be parsed into a valid
  64    ** DateTime and checked is false then return null, otherwise throw
  65    ** ParseErr.
  66    **
  67    static DateTime fromStr(Str s, Bool checked := true)
  68  
  69    **
  70    ** Private constructor.
  71    **
  72    private new privateMake()
  73  
  74  //////////////////////////////////////////////////////////////////////////
  75  // Identity
  76  //////////////////////////////////////////////////////////////////////////
  77  
  78    **
  79    ** Two times are equal if have identical nanosecond ticks.
  80    **
  81    override Bool equals(Obj that)
  82  
  83    **
  84    ** Return nanosecond ticks for the hashcode.
  85    **
  86    override Int hash()
  87  
  88    **
  89    ** Compare based on nanosecond ticks.
  90    **
  91    override Int compare(Obj obj)
  92  
  93    **
  94    ** Return programmatic string encoding formatted as follows:
  95    **   "YYYY-MM-DD'T'hh:mm:ss.FFFFFFFFFz zzzz"
  96    **
  97    ** See `toLocale` for the pattern legend.  The base of the
  98    ** string encoding conforms to ISO 8601 and XML Schema
  99    ** Part 2.  The Fan format also appends the timezone name to
 100    ** avoid the ambiguities associated with interpretting the time
 101    ** zone offset.
 102    **
 103    ** Examples:
 104    **   "2000-04-03T00:00:00.123Z UTC"
 105    **   "2006-10-31T01:02:03-05:00 New_York"
 106    **   "2009-03-10T11:33:20Z London"
 107    **   "2009-03-01T12:00:00+01:00 Amsterdam"
 108    **
 109    override Str toStr()
 110  
 111  //////////////////////////////////////////////////////////////////////////
 112  // Access
 113  //////////////////////////////////////////////////////////////////////////
 114  
 115    **
 116    ** Return number of nanosecond ticks since 1 Jan 2000 UTC.
 117    ** Dates before this epoch will return a negative integer.
 118    **
 119    Int ticks()
 120  
 121    **
 122    ** Get the year as a number such as 2007.
 123    **
 124    Int year()
 125  
 126    **
 127    ** Get the month of this date.
 128    **
 129    Month month()
 130  
 131    **
 132    ** Get the day of the month as a number between 1 and 31.
 133    **
 134    Int day()
 135  
 136    **
 137    ** Get the hour of the time as a number between 0 and 23.
 138    **
 139    Int hour()
 140  
 141    **
 142    ** Get the minutes of the time as a number between 0 and 59.
 143    **
 144    Int min()
 145  
 146    **
 147    ** Get the whole seconds of the time as a number between 0 and 59.
 148    **
 149    Int sec()
 150  
 151    **
 152    ** Get the number of nanoseconds (the fraction of seconds) as
 153    ** a number between 0 and 999,999,999.
 154    **
 155    Int nanoSec()
 156  
 157    **
 158    ** Get the day of the week for this time.
 159    **
 160    Weekday weekday()
 161  
 162    **
 163    ** Get the time zone associated with this date time.
 164    **
 165    TimeZone timeZone()
 166  
 167    **
 168    ** Return if this time is within daylight savings time
 169    ** for its associated time zone.
 170    **
 171    Bool dst()
 172  
 173    **
 174    ** Get the time zone's abbreviation for this time.
 175    ** See `TimeZone.stdAbbr` and `TimeZone.dstAbbr`.
 176    **
 177    Str timeZoneAbbr()
 178  
 179    **
 180    ** Return the day of the year as a number between
 181    ** 1 and 365 (or 1 to 366 if a leap year).
 182    **
 183    Int dayOfYear()
 184  
 185  //////////////////////////////////////////////////////////////////////////
 186  // Locale
 187  //////////////////////////////////////////////////////////////////////////
 188  
 189    **
 190    ** Format this time according to the specified pattern.  If
 191    ** pattern is null, then a localized default is used.  Any
 192    ** ASCII letter in the pattern is interpreted as follows:
 193    **
 194    **   YY     Two digit year             07
 195    **   YYYY   Four digit year            2007
 196    **   M      One/two digit month        6, 11
 197    **   MM     Two digit month            06, 11
 198    **   MMM    Three letter abbr month    Jun, Nov
 199    **   MMMM   Full month                 June, November
 200    **   D      One/two digit day          5, 28
 201    **   DD     Two digit day              05, 28
 202    **   WWW    Three letter abbr weekday  Tue
 203    **   WWWW   Full weekday               Tuesday
 204    **   h      One digit 24 hour (0-23)   3, 22
 205    **   hh     Two digit 24 hour (0-23)   03, 22
 206    **   k      One digit 12 hour (1-12)   3, 11
 207    **   kk     Two digit 12 hour (1-12)   03, 11
 208    **   m      One digit minutes (0-59)   4, 45
 209    **   mm     Two digit minutes (0-59)   04, 45
 210    **   s      One digit seconds (0-59)   4, 45
 211    **   ss     Two digit seconds (0-59)   04, 45
 212    **   f*     Fractional secs trailing zeros
 213    **   F*     Fractional secs no trailing zeros
 214    **   a      AM/PM marker               AM, PM
 215    **   z      Time zone offset           Z, +03:00 (ISO 8601, XML Schema)
 216    **   zzz    Time zone abbr             EST, EDT
 217    **   zzzz   Time zone name             New_York
 218    **   'xyz'  Literal characters
 219    **
 220    ** A symbol immediately preceding a "F" pattern with a no
 221    ** fraction to print is skipped.
 222    **
 223    Str toLocale(Str pattern := null)
 224  
 225  //////////////////////////////////////////////////////////////////////////
 226  // Utils
 227  //////////////////////////////////////////////////////////////////////////
 228  
 229    **
 230    ** Convert this DateTime to the specific timezone.  The
 231    ** absolute point time as ticks remains the same, but the
 232    ** date and time fields will be converted to represent the
 233    ** new time zone.
 234    **
 235    DateTime toTimeZone(TimeZone tz)
 236  
 237    **
 238    ** Return the delta between this and the given time.
 239    **
 240    ** Example:
 241    **   elapsed := DateTime.now - startTime
 242    **
 243    Duration minus(DateTime time)
 244  
 245    **
 246    ** Add (or subtract if duration is negative) a duration
 247    ** to compute a new time.
 248    **
 249    ** Example:
 250    **   tomorrow  := DateTime.now + 1days
 251    **   yesterday := DateTime.now + -1days
 252    **
 253    DateTime plus(Duration duration)
 254  
 255    **
 256    ** Return a new DateTime with this time's nanosecond ticks truncated
 257    ** according to the specified accuracy.  For example 'floor(1min)'
 258    ** will truncate this time to the minute such that seconds
 259    ** are 0.0.  This method is strictly based on absolute ticks,
 260    ** it does not take into account wall-time rollovers.
 261    **
 262    DateTime floor(Duration accuracy)
 263  
 264    **
 265    ** Return if the specified year is a leap year.
 266    **
 267    static Bool isLeapYear(Int year)
 268  
 269    **
 270    ** This method computes the day of month (1-31) for a given
 271    ** weekday.  The pos parameter specifies the first, second,
 272    ** third, or fourth occurence of the weekday.  A negative pos
 273    ** is used to compute the last (or second to last, etc) weekday
 274    ** in the month.
 275    **
 276    ** Examples:
 277    **   // compute the second monday in Apr 2007
 278    **   weekdayInMonth(2007, Month.apr, Weekday.mon, 2)
 279    **
 280    **   // compute the last sunday in Oct 2007
 281    **   weekdayInMonth(2007, Month.oct, Weekday.sun, -1)
 282    **
 283    static Int weekdayInMonth(Int year, Month mon, Weekday weekday, Int pos)
 284  
 285  //////////////////////////////////////////////////////////////////////////
 286  // HTTP
 287  //////////////////////////////////////////////////////////////////////////
 288  
 289    **
 290    ** Parse an HTTP date according to the RFC 2616 section 3.3.1.  If
 291    ** invalid format and checked is false return null, otherwise
 292    ** throw ParseErr.  The following date formats are supported:
 293    **
 294    **   Sun, 06 Nov 1994 08:49:37 GMT  ; RFC 822, updated by RFC 1123
 295    **   Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
 296    **   Sun Nov  6 08:49:37 1994       ; ANSI C's asctime() format
 297    **
 298    static DateTime fromHttpStr(Str s, Bool checked := true)
 299  
 300    **
 301    ** Format this time for use in an MIME or HTTP message
 302    ** according to RFC 2616 using the RFC 1123 format:
 303    **
 304    **   Sun, 06 Nov 1994 08:49:37 GMT
 305    **
 306    Str toHttpStr()
 307  
 308  
 309  }