Changeset 51

Show
Ignore:
Timestamp:
03/28/06 11:04:26 (6 years ago)
Author:
PeyloW
Message:

Rearranged functions and did soem new ones to make timestamp more consistent

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/date.d

    r50 r51  
    252252 
    253253/** 
    254  * Create a string from a d_date date. 
    255  * 
    256  * Params: 
    257  *  date =         A d_date date. 
    258  *  format =       An optional format string, defaults to ISO 8601. 
    259  * 
    260  * Returns: The d_date date as a string. 
    261  */ 
    262 public char[] toString(d_date date, char[] format = ISO_FORMAT_DATE) { 
    263   assert(format == ISO_FORMAT_DATE); 
    264   int year, month, day; 
    265   splitDate(date, year, month, day); 
    266   return std.string.format("%04d-%02d-%02d", year, month, day); 
     254 * Get current system local time. 
     255 * 
     256 * Returns: Current system local time as a d_time time. 
     257 */ 
     258public d_time time() { 
     259  tm* _tm = localtime(null); 
     260  d_time time = toTime(_tm.tm_hour, _tm.tm_min, _tm.tm_sec, 0); 
     261  //free(tm); 
     262  return time; 
     263
     264 
     265 
     266/** 
     267 * Get current system UDT time. 
     268 * 
     269 * Returns: Current system UDT time as a d_time time. 
     270 */ 
     271public d_time udtTime() { 
     272  tm* _tm = gmtime(null); 
     273  d_time time = toTime(_tm.tm_hour, _tm.tm_min, _tm.tm_sec, 0); 
     274  //free(tm); 
     275  return time; 
    267276} 
    268277 
     
    360369 *  day =          A day of month. 
    361370 * 
    362  * Returns: Date as a d_time. 
     371 * Returns: Date as a d_date. 
    363372 */ 
    364373public d_date toDate(int year, int month, int day) { 
     
    387396 
    388397/** 
     398 * Creates a date from a timestamp. 
     399 * 
     400 * Params: 
     401 *  timestamp =    A d_timestamp date/time. 
     402 * 
     403 * Return: A d_date date. 
     404 */ 
     405public d_date toDate(d_timestamp timestamp) { 
     406  return cast(d_date)timestamp; 
     407} 
     408 
     409 
     410/** 
    389411 * Creates a date from an *nix epoch. 
    390412 * 
     
    398420  epoch -= DATE_UNIX_EPOCH_OFFSET; 
    399421  return cast(d_date)epoch; 
     422} 
     423 
     424 
     425/** 
     426 * Crates a d_time time from a string. 
     427 * 
     428 * Params: 
     429 *  timeString =   A time astring. 
     430 *  format =       An optional format string, defaults to ISO 8601. 
     431 * 
     432 * Returns: A d_time time. 
     433 */ 
     434public d_time toTime(char[] timeString) { 
     435  d_datetime datetime; 
     436  char[][] fields; 
     437  FieldType[] ftypes; 
     438  FieldType dtype; 
     439  if (!parseDateTime(timeString, fields, ftypes)) { 
     440    throw new ParseDateException(timeString ~ " can not be parsed as time"); 
     441  } 
     442  if (!decodeDateTime(fields, ftypes, dtype, datetime, false)) { 
     443    throw new ParseDateException(timeString ~ " can not be parsed as time"); 
     444  } 
     445  switch (dtype) { 
     446    case FieldType.TIME: 
     447      break; 
     448    case FieldType.EPOCH: 
     449      assert(0); 
     450    default: 
     451    throw new ParseDateException(timeString ~ " can not be parsed as time"); 
     452  } 
     453  return toTime(datetime.hour, datetime.minute, datetime.second, datetime.millisecond); 
     454} 
     455unittest { 
     456  // Also tests toTime(int, int, int) and toString(), splitTime() 
     457  d_time t = toTime("12:01:02"); 
     458  assert(toString(t) == "12:01:02"); 
     459  assert(t == toTime(12, 1, 2)); 
     460// TODO: Allow for compact ISO times. 
     461//  assert(t == toTime("120102")); 
     462  assert(t == toTime("12:01:02.000")); 
     463  assert(t == toTime("00:01:02 PM")); 
     464  int h, m, s, ms; 
     465  splitTime(t, h, m, s, ms); 
     466  assert(h == 12); 
     467  assert(m == 1); 
     468  assert(s == 2); 
     469  assert(ms == 0); 
     470} 
     471 
     472 
     473/** 
     474 * Compose a d_time time from a hour, minute, second and millisecond part. 
     475 * 
     476 * Params: 
     477 *  hour =         An hour. 
     478 *  minute =       A minute. 
     479 *  second =       A second. 
     480 *  millisecond =  An optional millisecond, defaults to 0. 
     481 * 
     482 * Returns: Time as d_time. 
     483 */ 
     484public d_time toTime(int hour, int minute, int second, int millisecond = 0) { 
     485  d_time time; 
     486  time = cast(d_time)(MSEC_PER_HOUR * hour +  
     487                      MSEC_PER_MIN * minute + 
     488                      MSEC_PER_SEC * second + 
     489                      millisecond); 
     490  return normTime(time); 
     491} 
     492 
     493 
     494/** 
     495 * Creates a time from a timestamp. 
     496 * 
     497 * Params: 
     498 *  timestamp =    A d_timestamp date/time. 
     499 * 
     500 * Return: A d_time time. 
     501 */ 
     502public d_time toTime(d_timestamp timestamp) { 
     503  double d = cast(double)timestamp % 1.0; 
     504  if (d < 0.0) { 
     505    d += 1.0; 
     506  } 
     507  return cast(d_time)(d * MSEC_PER_DAY); 
     508} 
     509 
     510 
     511/** 
     512 * Crates a d_timestamp date/time from a string. 
     513 * 
     514 * Params: 
     515 *  tsString =     A date and time time string. 
     516 *  format =       An optional format string, defaults to ISO 8601. 
     517 * 
     518 * Returns: A d_timestamp date/time. 
     519 */ 
     520public d_timestamp toTimeStamp(char[] tsString) { 
     521  d_datetime datetime; 
     522  char[][] fields; 
     523  FieldType[] ftypes; 
     524  FieldType dtype; 
     525  if (!parseDateTime(tsString, fields, ftypes)) { 
     526    throw new ParseDateException(tsString ~ " can not be parsed as timestamp"); 
     527  } 
     528  if (!decodeDateTime(fields, ftypes, dtype, datetime, false)) { 
     529    throw new ParseDateException(tsString ~ " can not be parsed as timestamp"); 
     530  } 
     531  switch (dtype) { 
     532    case FieldType.DATE: 
     533      break; 
     534    case FieldType.EPOCH: 
     535      assert(0); 
     536    default: 
     537    throw new ParseDateException(tsString ~ " can not be parsed as timestamp"); 
     538  } 
     539  d_date date = toDate(datetime.year, datetime.month, datetime.day); 
     540  d_time time = toTime(datetime.hour, datetime.minute, datetime.second, datetime.millisecond); 
     541  return toTimeStamp(date, time); 
     542} 
     543unittest { 
     544  // Also tests toTimeStamp(int, int...), toTimeStamp(date, time), 
     545  // toTimeStamp(int), toString(), and splitTimeStamp() 
     546  d_timestamp ts = toTimeStamp("2006-03-19 11:42:00"); 
     547  assert(ts == toTimeStamp(toDate("2006-03-19"), toTime("11:42:00"))); 
     548  assert(toString(toTimeStamp(0)) == "1970-01-01 00:00:00"); 
     549  d_date d = toDate(ts); 
     550  d_time t = toTime(ts); 
     551  assert(d == toDate(2006,3,19)); 
     552  assert(t == toTime(11, 42, 0));  
     553} 
     554 
     555 
     556/** 
     557 * Convert a d_date date to a d_timestamp date/time. 
     558 * 
     559 * Params: 
     560 *  date =         A d_date date. 
     561 * 
     562 * Returns: A d_timestamp date/time. 
     563 */ 
     564public d_timestamp toTimeStamp(d_date date) { 
     565  return cast(d_timestamp)date; 
     566} 
     567 
     568 
     569/** 
     570 * Convert a d_time time to a d_timestamp date/time. 
     571 * 
     572 * Datepart will be today. 
     573 * 
     574 * Params: 
     575 *  time =         A d_time time. 
     576 * 
     577 * Returns: A d_timestamp date/time. 
     578 */ 
     579public d_timestamp toTimeStamp(d_time time) { 
     580  return cast(d_timestamp)date() + cast(d_timestamp)(cast(double)time /  
     581      MSEC_PER_DAY); 
     582} 
     583 
     584 
     585/** 
     586 * Convert a d_date date and a d_time time to a d_timestamp date/time. 
     587 * 
     588 * Params: 
     589 *  date =         A d_date date. 
     590 *  time =         A d_time time. 
     591 * 
     592 * Returns: A d_timestamp date/time. 
     593 */ 
     594public d_timestamp toTimeStamp(d_date date, d_time time) { 
     595  return cast(d_timestamp)date + cast(d_timestamp)(cast(double)time /  
     596      MSEC_PER_DAY); 
     597} 
     598 
     599 
     600/** 
     601 * Compose a d_timestamp from a year, a month, and a day components. 
     602 * 
     603 * Values less than 1 indicates days from the end of the month, 0 is the last  
     604 * day of the month, and -1 is the second to last, etc. 
     605 * 
     606 * Days that does not fit into a month will spill into the next month. Day 35 of 
     607 * january will for example result in the 4th of february. 
     608 * 
     609 * Params: 
     610 *  year =         A year. 
     611 *  month =        A month of year. 
     612 *  day =          A day of month. 
     613 *  hour =         An hour. 
     614 *  minute =       A minute. 
     615 *  second =       A second. 
     616 *  millisecond =  An optional millisecond, defaults to 0. 
     617 * 
     618 * Returns: Date/time as a d_timestamp. 
     619 */ 
     620public d_timestamp toTimeStamp(int year, int month, int day, int hour,  
     621    int minute, int second, int millisecond = 0) { 
     622  return toTimeStamp(toDate(year, month, day), toTime(hour, minute, second,  
     623      millisecond)); 
     624} 
     625 
     626 
     627/** 
     628 * Compose a d_timestamp from a year, month, day, hour, minute, second, and  
     629 * millisecond part. 
     630 * 
     631 * Values less than 1 indicates days from the end of the month, 0 is the last  
     632 * day of the month, and -1 is the second to last, etc. 
     633 * 
     634 * Days that does not fit into a month will spill into the next month. Day 35 of 
     635 * january will for example result in the 4th of february. 
     636 * 
     637 * Params: 
     638 *  year =         A year. 
     639 *  month =        A month of year. 
     640 *  day =          A day of month. 
     641 * 
     642 * Returns: Date as a d_timestamp. 
     643 */ 
     644public d_timestamp toDateTimeStamp(int year, int month, int day) { 
     645  return toTimeStamp(toDate(year, month, day)); 
     646} 
     647 
     648 
     649/** 
     650 * Compose a d_timestamp time from a hour, minute, second and millisecond part. 
     651 * 
     652 * Params: 
     653 *  hour =         An hour. 
     654 *  minute =       A minute. 
     655 *  second =       A second. 
     656 *  millisecond =  An optional millisecond, defaults to 0. 
     657 * 
     658 * Returns: Time as d_timestamp. 
     659 */ 
     660public d_timestamp toTimeTimeStamp(int hour, int minute, int second,  
     661    int millisecond) { 
     662  return toTimeStamp(toTime(hour, minute, second, millisecond)); 
     663} 
     664 
     665 
     666/** 
     667 * Creates a date/time from an *nix epoch. 
     668 * 
     669 * Params: 
     670 *  epoch =        An *nix epoch. 
     671 * 
     672 * Return: A d_timestamp date/time. 
     673 */ 
     674public d_timestamp toTimeStamp(int epoch) { 
     675  double timestamp; 
     676  timestamp = cast(double)epoch / SEC_PER_DAY; 
     677  timestamp -= DATE_UNIX_EPOCH_OFFSET; 
     678  return cast(d_timestamp)timestamp; 
     679} 
     680 
     681 
     682/** 
     683 * Creates an d_duration duration from a string. 
     684 * 
     685 * Params: 
     686 *  durationString = A date string. 
     687 * 
     688 * Returns: An d_duration duration. 
     689 */ 
     690public d_duration toDuration(char[] durationString) { 
     691  d_datetime datetime; 
     692  char[][] fields; 
     693  FieldType[] ftypes; 
     694  if (!parseDateTime(durationString, fields, ftypes)) { 
     695    throw new ParseDateException(durationString ~ " can not be parsed as duration"); 
     696  } 
     697  if (!decodeDuration(fields, ftypes, datetime)) { 
     698    throw new ParseDateException(durationString ~ " can not be parsed as duration"); 
     699  } 
     700  return toDuration(datetime.year, datetime.month, datetime.day,  
     701      datetime.hour, datetime.minute, datetime.second, datetime.millisecond); 
     702} 
     703unittest { 
     704  d_duration d = toDateDuration(1, 2, 3); 
     705  assert(d == toDuration("1 year, 2 months and 3 days"));  
     706} 
     707 
     708 
     709/** 
     710 * Creates an d_duration duration from years, months, days, hours, minutes, 
     711 * seconds and milliseconds parts. 
     712 * 
     713 * Params: 
     714 *  years =        Number of years. 
     715 *  months =       Number of months. 
     716 *  days =         Number of days. 
     717 *  hours =        Numbr of hours. 
     718 *  minutes =      Number of minutes. 
     719 *  seconds =      Number of seconds. 
     720 *  milliseconds = Optional number of milliseconds, defaults to 0. 
     721 * 
     722 * Returns: An d_duration duration. 
     723 */ 
     724public d_duration toDuration(int years, int months, int days, int hours,  
     725    int minutes, int seconds, int milliseconds = 0) { 
     726  d_duration duration; 
     727  duration.daysAndTime = cast(double)days + 
     728                         (1.0 / HOUR_PER_DAY) * hours +  
     729                         (1.0 / MIN_PER_DAY) * minutes + 
     730                         (1.0 / SEC_PER_DAY) * seconds + 
     731                         (1.0 / MSEC_PER_DAY) * milliseconds; 
     732  duration.months = years * 12 + months; 
     733  return duration; 
     734} 
     735 
     736 
     737/** 
     738 * Creates an d_duration duration from years, months, and days parts. 
     739 * 
     740 * Params: 
     741 *  years =        Number of years. 
     742 *  months =       Number of months. 
     743 *  days =         Number of days. 
     744 * 
     745 * Returns: An d_duration duration. 
     746 */ 
     747public d_duration toDateDuration(int years, int months, int days) { 
     748  return toDuration(years, months, days, 0, 0, 0); 
     749} 
     750 
     751 
     752/** 
     753 * Creates an d_duration duration from hours, minutes, seconds and milliseconds  
     754 * parts. 
     755 * 
     756 * Params: 
     757 *  hours =        Numbr of hours. 
     758 *  minutes =      Number of minutes. 
     759 *  seconds =      Number of seconds. 
     760 *  milliseconds = Optional number of milliseconds, defaults to 0. 
     761 * 
     762 * Returns: An d_duration duration. 
     763 */ 
     764public d_duration toTimeDuration(int hours, int minutes, int seconds, int milliseconds = 0) { 
     765  return toDuration(0, 0, 0, hours, minutes, seconds, milliseconds); 
     766} 
     767 
     768 
     769/** 
     770 * Return the difference between two d_date dates as a d_duration duration. 
     771 * 
     772 * The difference can be extracted as an exact measure in days (default), and 
     773 * optionally in relative measure by months and years. 
     774 * 
     775 * Params: 
     776 *  fromDate =     A base d_date date. 
     777 *  toDate =       A relative d_date date. 
     778 *  relative =     If true duration is relative. 
     779 * 
     780 * Returns: A d_duration duration. 
     781 */ 
     782public d_duration age(d_date fromDate, d_date toDate, bool relative = false) { 
     783  d_duration duration; 
     784   
     785  if (!relative) { 
     786    duration.daysAndTime = cast(double)(toDate - fromDate); 
     787  } else { 
     788    int fromYear, fromMonth, fromDay; 
     789    int toYear, toMonth, toDay; 
     790    splitDate(fromDate, fromYear, fromMonth, fromDay); 
     791    splitDate(toDate, toYear, toMonth, toDay); 
     792    duration.daysAndTime = cast(double)(toDay - fromDay); 
     793    duration.months = (toYear * 12 + toMonth) - (fromYear * 12 + fromMonth); 
     794  } 
     795  return duration; 
     796} 
     797 
     798 
     799/** 
     800 * Return the difference between two d_time times as a d_duration duration. 
     801 * 
     802 * Params: 
     803 *  fromTime =     A base d_time time. 
     804 *  toTime =       A relative d_time time. 
     805 * 
     806 * Returns: A d_duration duration. 
     807 */ 
     808public d_duration age(d_time fromTime, d_time toTime) { 
     809  d_duration duration; 
     810  duration.daysAndTime = cast(double)(toTime - fromTime); 
     811  return duration; 
     812} 
     813 
     814 
     815/** 
     816 * Return the difference between two d_timestamp date/times as a d_duration  
     817 * duration. 
     818 * 
     819 * The difference can be extracted as an exact measure in days (default), and 
     820 * optionally in relative measure by months and years. 
     821 * 
     822 * Params: 
     823 *  fromTimeStamp = A base d_timestamp date/time. 
     824 *  toTimeStamp =  A relative d_timestamp date/time. 
     825 *  relative =     If true duration is relative. 
     826 * 
     827 * Returns: A d_duration duration. 
     828 */ 
     829public d_duration age(d_timestamp fromTimeStamp, d_timestamp toTimeStamp,  
     830    bool relative = false) { 
     831  d_duration duration; 
     832 
     833  duration = age(toDate(fromTimeStamp), toDate(toTimeStamp), relative); 
     834  duration.daysAndTime += cast(double)(toTime(toTimeStamp) -   
     835      toTime(fromTimeStamp)); 
     836  return duration;  
    400837} 
    401838 
     
    445882    month = (quad + 10) % 12 + 1; 
    446883    day = date - 7834 * quad / 256; 
     884} 
     885 
     886 
     887/** 
     888 * Split a d_time into hour, minute, second, and millisecond parts. 
     889 * 
     890 * Params:  
     891 *  time =         A d_time time. 
     892 *  hour =         (OUT) The hour. 
     893 *  minute =       (OUT) The minute. 
     894 *  second =       (OUT) The second. 
     895 *  millisecond =  (OUT) The millisecond. 
     896 */ 
     897public void splitTime(d_time time, out int hour, out int minute, out int second,  
     898    out int millisecond) { 
     899  time = normTime(time); 
     900  hour = cast(int)time / MSEC_PER_HOUR; 
     901  minute = cast(int)(time / MSEC_PER_MIN) % 60; 
     902  second = cast(int)(time / MSEC_PER_SEC) % 60; 
     903  millisecond = cast(int)time % 1000; 
     904} 
     905 
     906 
     907/** 
     908 * Split a d_timestamp time into year, month, day, hour, minute, second, and  
     909 * millisecond parts. 
     910 * 
     911 * Params: 
     912 *  timestamp =    A d_timestamp date/time. 
     913 *  year =         (OUT) The year. 
     914 *  month =        (OUT) The month of year. 
     915 *  day =          (OUT) The day of month. 
     916 *  hour =         (OUT) The hour. 
     917 *  minute =       (OUT) The minute. 
     918 *  second =       (OUT) The second. 
     919 *  millisecond =  (OUT) The millisecond. 
     920 */ 
     921public void splitTimeStamp(d_timestamp timestamp, out int year,  
     922    out int month, out int day, out int hour, out int minute, out int second, 
     923    out int millisecond) { 
     924  splitDate(toDate(timestamp), year, month, day); 
     925  splitTime(toTime(timestamp), hour, minute, second, millisecond); 
     926} 
     927 
     928 
     929/** 
     930 * Split a d_timestamp into year, month, and day components. 
     931 * 
     932 * Params: 
     933 *  timestamp =    A d_timestamp date/time. 
     934 *  year =         (OUT) The year. 
     935 *  month =        (OUT) The month of year. 
     936 *  day =          (OUT) The day of month. 
     937 */ 
     938public void splitDateTimeStamp(d_timestamp timestamp, out int year,  
     939    out int month, out int day) { 
     940  splitDate(toDate(timestamp), year, month, day); 
     941} 
     942 
     943 
     944/** 
     945 * Split a d_timestamp time into hour, minute, second, and millisecond parts. 
     946 * 
     947 * Params:  
     948 *  timestamp =    A d_timestamp date/time. 
     949 *  hour =         (OUT) The hour. 
     950 *  minute =       (OUT) The minute. 
     951 *  second =       (OUT) The second. 
     952 *  millisecond =  (OUT) The millisecond. 
     953 */ 
     954public void splitTimeTimeStamp(d_timestamp timestamp, out int hour,  
     955    out int minute, out int second, out int millisecond) { 
     956  splitTime(toTime(timestamp), hour, minute, second, millisecond); 
     957} 
     958 
     959 
     960/** 
     961 * Splits an d_duration duration into years, months, days, hours, minutes, 
     962 * seconds and milliseconds parts. 
     963 * 
     964 * Params: 
     965 *  years =        (OUT) Number of years. 
     966 *  months =       (OUT) Number of months. 
     967 *  days =         (OUT) Number of days. 
     968 *  hours =        (OUT) Numbr of hours. 
     969 *  minutes =      (OUT) Number of minutes. 
     970 *  seconds =      (OUT) Number of seconds. 
     971 *  milliseconds = (OUT) Number of milliseconds. 
     972 */ 
     973public void splitDuration(d_duration duration, out int years, out int months,  
     974    out int days, out int hours, out int minutes, out int seconds, out int milliseconds) { 
     975  years = duration.months / 12; 
     976  months = duration.months % 12; 
     977  days = cast(int)duration.daysAndTime; 
     978  float timePart = duration.daysAndTime - days; 
     979  hours = cast(int)((timePart * HOUR_PER_DAY) % 24); 
     980  minutes = cast(int)((timePart * MIN_PER_DAY) % 60); 
     981  seconds = cast(int)((timePart * SEC_PER_DAY) % 60); 
     982  milliseconds = cast(int)((timePart * MSEC_PER_DAY) % 1000); 
     983} 
     984 
     985 
     986/** 
     987 * Splits an d_duration duration into years, months, and days parts. 
     988 * 
     989 * Params: 
     990 *  years =        (OUT) Number of years. 
     991 *  months =       (OUT) Number of months. 
     992 *  days =         (OUT) Number of days. 
     993 */ 
     994public void splitDateDuration(d_duration duration, out int years,  
     995    out int months, out int days) { 
     996  years = duration.months / 12; 
     997  months = duration.months % 12; 
     998  days = cast(int)duration.daysAndTime; 
     999  // float timePart = duration.daysAndTime - days; 
     1000} 
     1001 
     1002 
     1003/** 
     1004 * Splits an d_duration duration into hours, minutes, seconds and milliseconds  
     1005 * parts. 
     1006 * 
     1007 * The days of the duration will be converted to hours, any months and/or years 
     1008 * will be ignored as their length in hours can not be determined. 
     1009 * 
     1010 * Params: 
     1011 *  hours =        (OUT) Numbr of hours. 
     1012 *  minutes =      (OUT) Number of minutes. 
     1013 *  seconds =      (OUT) Number of seconds. 
     1014 *  milliseconds = (OUT) Number of milliseconds. 
     1015 * 
     1016 */ 
     1017public void splitTimeDuration(d_duration duration, out int hours,  
     1018    out int minutes, out int seconds, out int milliseconds) { 
     1019  double timePart = duration.daysAndTime; 
     1020  hours = cast(int)(timePart * HOUR_PER_DAY);  
     1021  minutes = cast(int)((timePart * MIN_PER_DAY) % 60); 
     1022  seconds = cast(int)((timePart * SEC_PER_DAY) % 60); 
     1023  milliseconds = cast(int)((timePart * MSEC_PER_DAY) % 1000); 
    4471024} 
    4481025 
     
    5171094 
    5181095/** 
    519  * Incremet a d_date date's date part datePart by a count. 
    520  * 
    521  * Params: 
    522  *  date =         A d_date date. 
    523  *  datePart =     A DatePart dat part, in range MILLENIA..DAY. 
    524  *  count =        A count of dateparts to increment. 
    525  * 
    526  * Returns: A d_date date. 
    527  */ 
    528 public d_date increment(d_date date, DatePart datePart, int count) { 
    529   switch (datePart) { 
    530     case DatePart.MILLENIA: 
    531       return addYearsToDate(date, count * 1000); 
    532     case DatePart.DECADE: 
    533       return addYearsToDate(date, count * 10); 
    534     case DatePart.YEAR: 
    535       return addYearsToDate(date, count); 
    536     case DatePart.QUARTER: 
    537       return addMonthsToDate(date, count * 3); 
    538     case DatePart.MONTH: 
    539       return addMonthsToDate(date, count); 
    540     case DatePart.WEEK: 
    541       return date + count * 7; 
    542     case DatePart.DAY: 
    543       return date + count; 
    544     default: 
    545       throw new InvalidDatePartException(std.string.toString(cast(int)datePart) ~  
    546           " is an invalid date part"); 
    547   } 
    548 } 
    549  
    550  
    551 /** 
    552  * Increment d_date date with a d_duration duration. 
    553  * 
    554  * Params: 
    555  *  date =         A d_date date. 
    556  *  duration =     A d_duration duration. 
    557  * 
    558  * Returns: A d_date date. 
    559  */ 
    560 public d_date increment(d_date date, d_duration duration) { 
    561   return addMonthsToDate(date, duration.months) + cast(int)duration.daysAndTime; 
    562 } 
    563   
    564  
    565 /** 
    566  * Trunc a d_date date to a given date part. 
    567  * 
    568  * Params: 
    569  *  date =         A d_date date. 
    570  *  datePart =     A DatePart, in the range MILLENIA..WEEK. 
    571  * 
    572  * Returns: A d_date date. 
    573  */ 
    574 public d_date truncate(d_date date, DatePart datePart) { 
    575   int year, month, day; 
    576   splitDate(date, year, month, day); 
    577   switch (datePart) { 
    578     case DatePart.MILLENIA: 
    579       year = (year / 1000) * 1000; 
    580       month = 1; 
    581       day = 1; 
    582       break; 
    583     case DatePart.DECADE: 
    584       year = (year / 10) * 10; 
    585       month = 1; 
    586       day = 1; 
    587       break; 
    588     case DatePart.YEAR: 
    589       month = 1; 
    590       day = 1; 
    591       break; 
    592     case DatePart.QUARTER: 
    593       month = ((month - 1) / 3) * 3 + 1; 
    594     case DatePart.MONTH: 
    595       day = 1; 
    596       break; 
    597     case DatePart.WEEK: 
    598       return date - weekDayOfDate(date); 
    599     default: 
    600       throw new InvalidDatePartException(std.string.toString(cast(int)datePart) ~  
    601           " is an invalid date part"); 
    602   } 
    603   return toDate(year, month, day); 
    604 } 
    605 unittest { 
    606   d_date d = toDate(2026, 10, 28); 
    607   assert(truncate(d, DatePart.MILLENIA) == toDate(2000, 1, 1)); 
    608   assert(truncate(d, DatePart.DECADE) == toDate(2020, 1, 1)); 
    609   assert(truncate(d, DatePart.YEAR) == toDate(2026, 1, 1)); 
    610   assert(truncate(d, DatePart.QUARTER) == toDate(2026, 10, 1)); 
    611   assert(truncate(d, DatePart.MONTH) == toDate(2026, 10, 1)); 
    612   assert(truncate(d, DatePart.WEEK) == toDate(2026, 10, 26));   
    613 } 
    614  
    615  
    616 /** 
    617  * Get current system local time. 
    618  * 
    619  * Returns: Current system local time as a d_time time. 
    620  */ 
    621 public d_time time() { 
    622   tm* _tm = localtime(null); 
    623   d_time time = toTime(_tm.tm_hour, _tm.tm_min, _tm.tm_sec, 0); 
    624   //free(tm); 
    625   return time; 
    626 } 
    627  
    628  
    629 /** 
    630  * Get current system UDT time. 
    631  * 
    632  * Returns: Current system UDT time as a d_time time. 
    633  */ 
    634 public d_time udtTime() { 
    635   tm* _tm = gmtime(null); 
    636   d_time time = toTime(_tm.tm_hour, _tm.tm_min, _tm.tm_sec, 0); 
    637   //free(tm); 
    638   return time; 
    639 } 
    640  
    641  
    642 /** 
    643  * Create a string from a d_time time. 
    644  * 
    645  * Params: 
    646  *  time =         A d_time time. 
    647  *  format =       An optional format string, defaults to ISO 8601. 
    648  * 
    649  * Returns: The d_time time as a string. 
    650  */ 
    651 public char[] toString(d_time time, char[] format = ISO_FORMAT_TIME) { 
    652   int hour, minute, second, millisecond; 
    653  
    654   assert(format == ISO_FORMAT_TIME); 
    655  
    656   splitTime(time, hour, minute, second, millisecond); 
    657   return std.string.format("%02d:%02d:%02d", hour, minute, second); 
    658 } 
    659   
    660   
    661 /** 
    662  * Crates a d_time time from a string. 
    663  * 
    664  * Params: 
    665  *  timeString =   A time astring. 
    666  *  format =       An optional format string, defaults to ISO 8601. 
    667  * 
    668  * Returns: A d_time time. 
    669  */ 
    670 public d_time toTime(char[] timeString) { 
    671   d_datetime datetime; 
    672   char[][] fields; 
    673   FieldType[] ftypes; 
    674   FieldType dtype; 
    675   if (!parseDateTime(timeString, fields, ftypes)) { 
    676     throw new ParseDateException(timeString ~ " can not be parsed as time"); 
    677   } 
    678   if (!decodeDateTime(fields, ftypes, dtype, datetime, false)) { 
    679     throw new ParseDateException(timeString ~ " can not be parsed as time"); 
    680   } 
    681   switch (dtype) { 
    682     case FieldType.TIME: 
    683       break; 
    684     case FieldType.EPOCH: 
    685       assert(0); 
    686     default: 
    687     throw new ParseDateException(timeString ~ " can not be parsed as time"); 
    688   } 
    689   return toTime(datetime.hour, datetime.minute, datetime.second, datetime.millisecond); 
    690 } 
    691 unittest { 
    692   // Also tests toTime(int, int, int) and toString(), splitTime() 
    693   d_time t = toTime("12:01:02"); 
    694   assert(toString(t) == "12:01:02"); 
    695   assert(t == toTime(12, 1, 2)); 
    696 // TODO: Allow for compact ISO times. 
    697 //  assert(t == toTime("120102")); 
    698   assert(t == toTime("12:01:02.000")); 
    699   assert(t == toTime("00:01:02 PM")); 
    700   int h, m, s, ms; 
    701   splitTime(t, h, m, s, ms); 
    702   assert(h == 12); 
    703   assert(m == 1); 
    704   assert(s == 2); 
    705   assert(ms == 0); 
    706 } 
    707  
    708  
    709 /** 
    710  * Compose a d_time time from a hour, minute, second and millisecond part. 
    711  * 
    712  * Params: 
    713  *  hour =         An hour. 
    714  *  minute =       A minute. 
    715  *  second =       A second. 
    716  *  millisecond =  An optional millisecond, defaults to 0. 
    717  * 
    718  * Returns: Time as d_time. 
    719  */ 
    720 public d_time toTime(int hour, int minute, int second, int millisecond = 0) { 
    721   d_time time; 
    722   time = cast(d_time)(MSEC_PER_HOUR * hour +  
    723                       MSEC_PER_MIN * minute + 
    724                       MSEC_PER_SEC * second + 
    725                       millisecond); 
    726   return normTime(time); 
    727 } 
    728  
    729  
    730 /** 
    731  * Split a d_time time into hour, minute, second, and millisecond parts. 
    732  * 
    733  * Params:  
    734  *  time =         A d_time time. 
    735  *  hour =         (OUT) The hour. 
    736  *  minute =       (OUT) The minute. 
    737  *  second =       (OUT) The second. 
    738  *  millisecond =  (OUT) The millisecond. 
    739  */ 
    740 public void splitTime(d_time time, out int hour, out int minute, out int second,  
    741     out int millisecond) { 
    742   time = normTime(time); 
    743   hour = cast(int)time / MSEC_PER_HOUR; 
    744   minute = cast(int)(time / MSEC_PER_MIN) % 60; 
    745   second = cast(int)(time / MSEC_PER_SEC) % 60; 
    746   millisecond = cast(int)time % 1000; 
    747 } 
    748  
    749  
    750 /** 
    7511096 * Get date part of a d_time time. 
    7521097 * 
     
    7861131 
    7871132/** 
    788  * Trunc a d_time time to a given date part. 
    789  * 
    790  * Params: 
    791  *  time =         A d_time date. 
    792  *  datePart =     A DatePart, in the range HOUR..SECOND. 
    793  * 
    794  * Returns: A d_time time. 
    795  */ 
    796 public d_time truncate(d_time time, DatePart datePart) { 
    797   time = normTime(time); 
    798   switch (datePart) { 
    799     case DatePart.HOUR: 
    800       return cast(d_time)(cast(int)(time / MSEC_PER_HOUR) * MSEC_PER_HOUR); 
    801     case DatePart.MINUTE: 
    802       return cast(d_time)(cast(int)(time / MSEC_PER_MIN) * MSEC_PER_MIN); 
    803     case DatePart.SECOND: 
    804       return cast(d_time)(cast(int)(time / MSEC_PER_SEC) * MSEC_PER_SEC); 
    805     default: 
    806       throw new InvalidDatePartException(std.string.toString(cast(int)datePart) ~  
    807           " is an invalid date part"); 
    808   } 
    809 } 
    810 unittest { 
    811   d_time t = toTime(12, 13, 14, 15); 
    812   assert(truncate(t, DatePart.SECOND) == toTime("12:13:14")); 
    813   assert(truncate(t, DatePart.MINUTE) == toTime("12:13:00")); 
    814   assert(truncate(t, DatePart.HOUR) == toTime("12:00:00")); 
    815 } 
    816  
    817  
    818 /** 
    819  * Incremet a d_time times's date part datePart by a count. 
    820  * 
    821  * Params: 
    822  *  time =         A d_time time. 
    823  *  datePart =     A DatePart date part, in range HOUR..MILLISECOND. 
    824  *  count =        A count of dateparts to increment. 
    825  * 
    826  * Returns: A d_time time. 
    827  */ 
    828 public d_time increment(d_time time, DatePart datePart, int count) { 
    829   switch (datePart) { 
    830     case DatePart.HOUR: 
    831       time += cast(d_time)(count * MSEC_PER_HOUR); 
    832       break; 
    833     case DatePart.MINUTE: 
    834       time += cast(d_time)(count * MSEC_PER_MIN); 
    835       break; 
    836     case DatePart.SECOND: 
    837       time += cast(d_time)(count * MSEC_PER_SEC); 
    838       break; 
    839     case DatePart.MILLISECOND: 
    840       time += cast(d_time)count; 
    841       break; 
    842     default: 
    843       throw new InvalidDatePartException(std.string.toString(cast(int)datePart) ~  
    844           " is an invalid date part"); 
    845   } 
    846   return normTime(time); 
    847 } 
    848  
    849  
    850 /** 
    851  * Increment d_time time with a d_duration duration. 
    852  * 
    853  * Params: 
    854  *  time =         A d_time time. 
    855  *  duration =     A d_duration duration. 
    856  * 
    857  * Returns: A d_time time. 
    858  */ 
    859 public d_time increment(d_time time, d_duration duration) { 
    860   time += cast(d_time)(duration.daysAndTime * MSEC_PER_DAY) % 
    861       MSEC_PER_DAY; 
    862   return normTime(time); 
    863 } 
    864  
    865  
    866 /** 
    867  * Create a string from a d_timestamp date/time. 
    868  * 
    869  * Params: 
    870  *  timestamp =    A timestamnp_t date/time. 
    871  *  format =       An optional format string, defaults to ISO 8601. 
    872  * 
    873  * Returns: The d_timestamp time as a string. 
    874  */ 
    875 public char[] toString(d_timestamp timestamp,  
    876     char[] format = ISO_FORMAT_TIMESTAMP) { 
    877   assert(format == ISO_FORMAT_TIMESTAMP); 
    878    
    879   return toString(dateOfTimeStamp(timestamp), format[0..8]) ~ " " ~ 
    880          toString(timeOfTimeStamp(timestamp), format[9..$]); 
    881 } 
    882   
    883   
    884 /** 
    885  * Crates a d_timestamp date/time from a string. 
    886  * 
    887  * Params: 
    888  *  tsString =     A date and time time string. 
    889  *  format =       An optional format string, defaults to ISO 8601. 
    890  * 
    891  * Returns: A d_timestamp date/time. 
    892  */ 
    893 public d_timestamp toTimeStamp(char[] tsString) { 
    894   d_datetime datetime; 
    895   char[][] fields; 
    896   FieldType[] ftypes; 
    897   FieldType dtype; 
    898   if (!parseDateTime(tsString, fields, ftypes)) { 
    899     throw new ParseDateException(tsString ~ " can not be parsed as timestamp"); 
    900   } 
    901   if (!decodeDateTime(fields, ftypes, dtype, datetime, false)) { 
    902     throw new ParseDateException(tsString ~ " can not be parsed as timestamp"); 
    903   } 
    904   switch (dtype) { 
    905     case FieldType.DATE: 
    906       break; 
    907     case FieldType.EPOCH: 
    908       assert(0); 
    909     default: 
    910     throw new ParseDateException(tsString ~ " can not be parsed as timestamp"); 
    911   } 
    912   d_date date = toDate(datetime.year, datetime.month, datetime.day); 
    913   d_time time = toTime(datetime.hour, datetime.minute, datetime.second, datetime.millisecond); 
    914   return toTimeStamp(date, time); 
    915 } 
    916 unittest { 
    917   // Also tests toTimeStamp(int, int...), toTimeStamp(date, time), 
    918   // toTimeStamp(int), toString(), and splitTimeStamp() 
    919   d_timestamp ts = toTimeStamp("2006-03-19 11:42:00"); 
    920   assert(ts == toTimeStamp(toDate("2006-03-19"), toTime("11:42:00"))); 
    921   assert(toString(toTimeStamp(0)) == "1970-01-01 00:00:00"); 
    922   d_date d; 
    923   d_time t; 
    924   splitTimeStamp(ts, d, t); 
    925   assert(d == toDate(2006,3,19)); 
    926   assert(t == toTime(11, 42, 0));  
    927 } 
    928  
    929  
    930 /** 
    931  * Convert a d_date date to a d_timestamp date/time. 
    932  * 
    933  * Params: 
    934  *  date =         A d_date date. 
    935  * 
    936  * Returns: A d_timestamp date/time. 
    937  */ 
    938 public d_timestamp toTimeStamp(d_date date) { 
    939   return cast(d_timestamp)date; 
    940 } 
    941  
    942  
    943 /** 
    944  * Convert a d_time time to a d_timestamp date/time. 
    945  * 
    946  * Params: 
    947  *  time =         A d_time time. 
    948  * 
    949  * Returns: A d_timestamp date/time. 
    950  */ 
    951 public d_timestamp toTimeStamp(d_time time) { 
    952   return cast(d_timestamp)date() + cast(d_timestamp)(cast(double)time /  
    953       MSEC_PER_DAY); 
    954 } 
    955  
    956  
    957 /** 
    958  * Convert a d_date date and a d_time time to a d_timestamp date/time. 
    959  * 
    960  * Params: 
    961  *  date =         A d_date date. 
    962  *  time =         A d_time time. 
    963  * 
    964  * Returns: A d_timestamp date/time. 
    965  */ 
    966 public d_timestamp toTimeStamp(d_date date, d_time time) { 
    967   return cast(d_timestamp)date + cast(d_timestamp)(cast(double)time /  
    968       MSEC_PER_DAY); 
    969 } 
    970  
    971  
    972 /** 
    973  * Creates a date/time from an *nix epoch. 
    974  * 
    975  * Params: 
    976  *  epoch =        An *nix epoch. 
    977  * 
    978  * Return: A d_timestamp date/time. 
    979  */ 
    980 public d_timestamp toTimeStamp(int epoch) { 
    981   double timestamp; 
    982   timestamp = cast(double)epoch / SEC_PER_DAY; 
    983   timestamp -= DATE_UNIX_EPOCH_OFFSET; 
    984   return cast(d_timestamp)timestamp; 
    985 } 
    986  
    987  
    988 /** 
    989  * Split a d_timestamp date/time into d_date date, and d_time time components. 
    990  * 
    991  * Params: 
    992  *  timestamp =    A timetamp_t date/time. 
    993  *  date =         (OUT) A d_date date. 
    994  *  time =         (OUT) A d_time time. 
    995  */ 
    996 public void splitTimeStamp(d_timestamp timestamp, out d_date date,  
    997     out d_time time) { 
    998   date = dateOfTimeStamp(timestamp); 
    999   time = timeOfTimeStamp(timestamp); 
    1000 } 
    1001  
    1002  
    1003  
    1004 /** 
    10051133 * Get date part of a d_timestamp date/time. 
    10061134 * 
     
    10121140 * Returns: The datepart of a date/time. 
    10131141 */ 
    1014 public int extract(d_timestamp timestamp, DatePart aDatePart) { 
    1015   if (aDatePart == DatePart.EPOCH) { 
     1142public int extract(d_timestamp timestamp, DatePart datePart) { 
     1143  if (datePart == DatePart.EPOCH) { 
    10161144    return cast(int)((cast(double)timestamp + DATE_UNIX_EPOCH_OFFSET) *  
    10171145        SEC_PER_DAY); 
    1018   } else if (aDatePart < DatePart.HOUR) { 
    1019     return extract(dateOfTimeStamp(timestamp), aDatePart); 
     1146  } else if (datePart < DatePart.HOUR) { 
     1147    return extract(toDate(timestamp), datePart); 
    10201148  } else { 
    1021     return extract(timeOfTimeStamp(timestamp), aDatePart);   
     1149    return extract(toTime(timestamp), datePart);   
    10221150  } 
    10231151} 
     
    10401168  assert(extract(ts, DatePart.MONTH) == 1); 
    10411169  assert(extract(ts, DatePart.YEAR) == 2005); 
    1042 } 
    1043  
    1044  
    1045 /** 
    1046  * Trunc a d_timestamp date to a given date part. 
    1047  * 
    1048  * Params: 
    1049  *  timestamp =         A d_timestamp date/time. 
    1050  *  datePart =     A DatePart, in the range MILLENIA..DAY, HOUR..SECOND. 
    1051  * 
    1052  * Returns: A d_timestamp date/time. 
    1053  */ 
    1054 public d_timestamp truncate(d_timestamp timestamp, DatePart datePart) { 
    1055   if (datePart == DatePart.DAY) { 
    1056     return cast(d_timestamp)(cast(int)timestamp); 
    1057   } else { 
    1058     if (datePart < DatePart.HOUR) { 
    1059       return toTimeStamp(truncate(dateOfTimeStamp(timestamp), datePart), 0); 
    1060     } else { 
    1061       return toTimeStamp(dateOfTimeStamp(timestamp),  
    1062           truncate(timeOfTimeStamp(timestamp), datePart)); 
    1063     } 
    1064   } 
    1065 } 
    1066 unittest { 
    1067   d_timestamp ts = toTimeStamp("2006-03-19 12:26:42"); 
    1068   assert(truncate(ts, DatePart.MINUTE) == toTimeStamp("2006-03-19 12:26:00")); 
    1069   assert(truncate(ts, DatePart.HOUR) == toTimeStamp("2006-03-19 12:00:00")); 
    1070   assert(truncate(ts, DatePart.DAY) == toTimeStamp("2006-03-19 00:00:00")); 
    1071   assert(truncate(ts, DatePart.WEEK) == toTimeStamp("2006-03-13 00:00:00")); 
    1072   assert(truncate(ts, DatePart.MONTH) == toTimeStamp("2006-03-01 00:00:00")); 
    1073   assert(truncate(ts, DatePart.QUARTER) == toTimeStamp("2006-01-01 00:00:00")); 
    1074   assert(truncate(ts, DatePart.YEAR) == toTimeStamp("2006-01-01 00:00:00")); 
    1075   assert(truncate(ts, DatePart.DECADE) == toTimeStamp("2000-01-01 00:00:00")); 
    1076   assert(truncate(ts, DatePart.MILLENIA) == toTimeStamp("2000-01-01 00:00:00")); 
    1077 } 
    1078  
    1079  
    1080 /** 
    1081  * Incremet a d_timestamp date/times's date part datePart by a count. 
    1082  * 
    1083  * Params: 
    1084  *  timestamp =    A d_timestamp date/time. 
    1085  *  datePart =     A DatePart date part, in range MILLENIA..MILLISECOND. 
    1086  *  count =        A count of dateparts to increment. 
    1087  * 
    1088  * Returns: A d_time time. 
    1089  */ 
    1090 public d_timestamp increment(d_timestamp timestamp, DatePart datePart, int count) { 
    1091   if (datePart < DatePart.HOUR) { 
    1092     return toTimeStamp(increment(dateOfTimeStamp(timestamp), datePart, count),  
    1093         timeOfTimeStamp(timestamp)); 
    1094   } else { 
    1095     switch (datePart) { 
    1096       case DatePart.HOUR: 
    1097         timestamp += cast(d_timestamp)(count * (1.0 / HOUR_PER_DAY)); 
    1098         break; 
    1099       case DatePart.MINUTE: 
    1100         timestamp += cast(d_timestamp)(count * (1.0 / MIN_PER_DAY)); 
    1101         break; 
    1102       case DatePart.SECOND: 
    1103         timestamp += cast(d_timestamp)(count * (1.0 / SEC_PER_DAY)); 
    1104         break; 
    1105       case DatePart.MILLISECOND: 
    1106         timestamp += cast(d_timestamp)(count * (1.0 / MSEC_PER_DAY)); 
    1107         break; 
    1108       default: 
    1109         throw new InvalidDatePartException(std.string.toString(cast(int)datePart) ~  
    1110             " is an invalid date part"); 
    1111     } 
    1112     return timestamp; 
    1113   } 
    1114 } 
    1115  
    1116  
    1117 /** 
    1118  * Increment d_timestamp date/time with a d_duration duration. 
    1119  * 
    1120  * Params: 
    1121  *  timestamp =    A d_time time. 
    1122  *  duration =     A d_duration duration. 
    1123  * 
    1124  * Returns: A d_timestamp date/time. 
    1125  */ 
    1126 public d_timestamp increment(d_timestamp timestamp, d_duration duration) { 
    1127   return increment(timestamp, DatePart.MONTH, duration.months) +  
    1128       cast(d_timestamp)duration.daysAndTime; 
    1129 } 
    1130  
    1131  
    1132 /** 
    1133  * Get the d_date date part of a d_timestamp date/time. 
    1134  * 
    1135  * Params: 
    1136  *  timestamp =    A d_timestamp date/time. 
    1137  * 
    1138  * Returns: A d_date date. 
    1139  */ 
    1140 public d_date dateOfTimeStamp(d_timestamp timestamp) { 
    1141   return cast(d_date)timestamp; 
    1142 } 
    1143  
    1144  
    1145 /** 
    1146  * Replace the date part of a d_timestamp date/time. 
    1147  * 
    1148  * Params: 
    1149  *  timestamp =    (INOUT) A d_timestamp date/time. 
    1150  *  date =         A d_date date. 
    1151  */ 
    1152 public void setDateOfTimeStamp(inout d_timestamp timestamp, d_date date) { 
    1153   timestamp = timestamp - cast(d_timestamp)(cast(long)timestamp) +  
    1154       cast(d_timestamp)date; 
    1155 } 
    1156  
    1157  
    1158 /** 
    1159  * Get the d_time date part of a d_timestamp date/time. 
    1160  * 
    1161  * Params: 
    1162  *  timestamp =    A d_timestamp date/time. 
    1163  * 
    1164  * Returns: A d_time time. 
    1165  */ 
    1166 public d_time timeOfTimeStamp(d_timestamp timestamp) { 
    1167   return cast(d_time)((cast(double)timestamp * MSEC_PER_DAY) % MSEC_PER_DAY); 
    1168 } 
    1169  
    1170  
    1171 /** 
    1172  * Replace the time part of a d_timestamp date/time. 
    1173  * 
    1174  * Params: 
    1175  *  timestamp =    (INOUT) A d_timestamp date/time. 
    1176  *  time =         A d_time time. 
    1177  */ 
    1178 public void setTimeOfTimeStamp(inout d_timestamp timestamp, d_time time) { 
    1179   timestamp = cast(d_timestamp)(cast(long)timestamp) +  
    1180       cast(d_timestamp)(cast(double)time / MSEC_PER_DAY); 
    1181 } 
    1182  
    1183  
    1184 /** 
    1185  * Create a string from a d_duration duration. 
    1186  * 
    1187  * Params: 
    1188  *  duration =     An d_duration duration. 
    1189  * 
    1190  * Returns: The d_duration duration as a string. 
    1191  */ 
    1192 public char[] toString(d_duration duration) { 
    1193   assert(0); 
    1194 } 
    1195  
    1196  
    1197 /** 
    1198  * Creates an d_duration duration from a string. 
    1199  * 
    1200  * Params: 
    1201  *  durationString = A date string. 
    1202  * 
    1203  * Returns: An d_duration duration. 
    1204  */ 
    1205 public d_duration toDuration(char[] durationString) { 
    1206   d_datetime datetime; 
    1207   char[][] fields; 
    1208   FieldType[] ftypes; 
    1209   if (!parseDateTime(durationString, fields, ftypes)) { 
    1210     throw new ParseDateException(durationString ~ " can not be parsed as duration"); 
    1211   } 
    1212   if (!decodeDuration(fields, ftypes, datetime)) { 
    1213     throw new ParseDateException(durationString ~ " can not be parsed as duration"); 
    1214   } 
    1215   return toDuration(datetime.year, datetime.month, datetime.day,  
    1216       datetime.hour, datetime.minute, datetime.second, datetime.millisecond); 
    1217 } 
    1218 unittest { 
    1219   d_duration d = toDateDuration(1, 2, 3); 
    1220   assert(d == toDuration("1 year, 2 months and 3 days"));  
    1221 } 
    1222  
    1223  
    1224 /** 
    1225  * Creates an d_duration duration from years, months, days, hours, minutes, 
    1226  * seconds and milliseconds parts. 
    1227  * 
    1228  * Params: 
    1229  *  years =        Number of years. 
    1230  *  months =       Number of months. 
    1231  *  days =         Number of days. 
    1232  *  hours =        Numbr of hours. 
    1233  *  minutes =      Number of minutes. 
    1234  *  seconds =      Number of seconds. 
    1235  *  milliseconds = Optional number of milliseconds, defaults to 0. 
    1236  * 
    1237  * Returns: An d_duration duration. 
    1238  */ 
    1239 public d_duration toDuration(int years, int months, int days, int hours,  
    1240     int minutes, int seconds, int milliseconds = 0) { 
    1241   d_duration duration; 
    1242   duration.daysAndTime = cast(double)days + 
    1243                          (1.0 / HOUR_PER_DAY) * hours +  
    1244                          (1.0 / MIN_PER_DAY) * minutes + 
    1245                          (1.0 / SEC_PER_DAY) * seconds + 
    1246                          (1.0 / MSEC_PER_DAY) * milliseconds; 
    1247   duration.months = years * 12 + months; 
    1248   return duration; 
    1249 } 
    1250  
    1251  
    1252 /** 
    1253  * Creates an d_duration duration from years, months, and days parts. 
    1254  * 
    1255  * Params: 
    1256  *  years =        Number of years. 
    1257  *  months =       Number of months. 
    1258  *  days =         Number of days. 
    1259  * 
    1260  * Returns: An d_duration duration. 
    1261  */ 
    1262 public d_duration toDateDuration(int years, int months, int days) { 
    1263   return toDuration(years, months, days, 0, 0, 0); 
    1264 } 
    1265  
    1266  
    1267 /** 
    1268  * Creates an d_duration duration from hours, minutes, seconds and milliseconds  
    1269  * parts. 
    1270  * 
    1271  * Params: 
    1272  *  hours =        Numbr of hours. 
    1273  *  minutes =      Number of minutes. 
    1274  *  seconds =      Number of seconds. 
    1275  *  milliseconds = Optional number of milliseconds, defaults to 0. 
    1276  * 
    1277  * Returns: An d_duration duration. 
    1278  */ 
    1279 public d_duration toTimeDuration(int hours, int minutes, int seconds, int milliseconds = 0) { 
    1280   return toDuration(0, 0, 0, hours, minutes, seconds, milliseconds); 
    1281 } 
    1282  
    1283  
    1284 /** 
    1285  * Splits an d_duration duration into years, months, days, hours, minutes, 
    1286  * seconds and milliseconds parts. 
    1287  * 
    1288  * Params: 
    1289  *  years =        (OUT) Number of years. 
    1290  *  months =       (OUT) Number of months. 
    1291  *  days =         (OUT) Number of days. 
    1292  *  hours =        (OUT) Numbr of hours. 
    1293  *  minutes =      (OUT) Number of minutes. 
    1294  *  seconds =      (OUT) Number of seconds. 
    1295  *  milliseconds = (OUT) Number of milliseconds. 
    1296  */ 
    1297 public void splitDuration(d_duration duration, out int years, out int months,  
    1298     out int days, out int hours, out int minutes, out int seconds, out int milliseconds) { 
    1299   years = duration.months / 12; 
    1300   months = duration.months % 12; 
    1301   days = cast(int)duration.daysAndTime; 
    1302   float timePart = duration.daysAndTime - days; 
    1303   hours = cast(int)((timePart * HOUR_PER_DAY) % 24); 
    1304   minutes = cast(int)((timePart * MIN_PER_DAY) % 60); 
    1305   seconds = cast(int)((timePart * SEC_PER_DAY) % 60); 
    1306   milliseconds = cast(int)((timePart * MSEC_PER_DAY) % 1000); 
    1307 } 
    1308  
    1309  
    1310 /** 
    1311  * Splits an d_duration duration into years, months, and days parts. 
    1312  * 
    1313  * Params: 
    1314  *  years =        (OUT) Number of years. 
    1315  *  months =       (OUT) Number of months. 
    1316  *  days =         (OUT) Number of days. 
    1317  */ 
    1318 public void splitDateDuration(d_duration duration, out int years,  
    1319     out int months, out int days) { 
    1320   years = duration.months / 12; 
    1321   months = duration.months % 12; 
    1322   days = cast(int)duration.daysAndTime; 
    1323   // float timePart = duration.daysAndTime - days; 
    1324 } 
    1325  
    1326  
    1327 /** 
    1328  * Splits an d_duration duration into hours, minutes, seconds and milliseconds  
    1329  * parts. 
    1330  * 
    1331  * The days of the duration will be converted to hours, any months and/or years 
    1332  * will be ignored as their length in hours can not be determined. 
    1333  * 
    1334  * Params: 
    1335  *  hours =        (OUT) Numbr of hours. 
    1336  *  minutes =      (OUT) Number of minutes. 
    1337  *  seconds =      (OUT) Number of seconds. 
    1338  *  milliseconds = (OUT) Number of milliseconds. 
    1339  * 
    1340  */ 
    1341 public void splitTimeDuration(d_duration duration, out int hours,  
    1342     out int minutes, out int seconds, out int milliseconds) { 
    1343   double timePart = duration.daysAndTime; 
    1344   hours = cast(int)(timePart * HOUR_PER_DAY);  
    1345   minutes = cast(int)((timePart * MIN_PER_DAY) % 60); 
    1346   seconds = cast(int)((timePart * SEC_PER_DAY) % 60); 
    1347   milliseconds = cast(int)((timePart * MSEC_PER_DAY) % 1000); 
    13481170} 
    13491171 
     
    14001222 
    14011223/** 
    1402  * Trunc an d_duration duration to a given date part. 
    1403  * 
    1404  * When truncing to dateparts in the range MILLENIA..MONTH all days will be 
    1405  * removed even if they theoretically could make up a larger date part. 
    1406  * 
    1407  * Params: 
    1408  *  duration =     An d_duration duration. 
    1409  *  datePart =     A DatePart, in the range MILLENIA..DAY, HOUR..SECOND. 
    1410  * 
    1411  * Returns: A d_timestamp date/time. 
    1412  */ 
    1413 public d_duration truncate(d_duration duration, DatePart datePart) { 
    1414   if (datePart < DatePart.WEEK) { 
    1415     duration.daysAndTime = 0.0; 
    1416   } 
     1224 * Incremet a d_date date's date part datePart by a count. 
     1225 * 
     1226 * Params: 
     1227 *  date =         A d_date date. 
     1228 *  datePart =     A DatePart dat part, in range MILLENIA..DAY. 
     1229 *  count =        A count of dateparts to increment. 
     1230 * 
     1231 * Returns: A d_date date. 
     1232 */ 
     1233public d_date increment(d_date date, DatePart datePart, int count) { 
    14171234  switch (datePart) { 
    14181235    case DatePart.MILLENIA: 
    1419       duration.months = (duration.months / (12 * 1000)) * (12 *1000); 
    1420       break; 
     1236      return addYearsToDate(date, count * 1000); 
    14211237    case DatePart.DECADE: 
    1422       duration.months = (duration.months / (12 * 10)) * (12 *1); 
    1423       break; 
     1238      return addYearsToDate(date, count * 10); 
    14241239    case DatePart.YEAR: 
    1425       duration.months = (duration.months / 12) * 12; 
    1426       break; 
     1240      return addYearsToDate(date, count); 
    14271241    case DatePart.QUARTER: 
    1428       duration.months = (duration.months / 3) * 3; 
    1429       break; 
     1242      return addMonthsToDate(date, count * 3); 
    14301243    case DatePart.MONTH: 
    1431       duration.months = (duration.months / (12 * 1000)) * (12 *1000); 
    1432       break; 
     1244      return addMonthsToDate(date, count); 
    14331245    case DatePart.WEEK: 
    1434       duration.daysAndTime = cast(int)(duration.daysAndTime / 7) *  
    1435           cast(double)7.0; 
    1436       break; 
     1246      return date + count * 7; 
    14371247    case DatePart.DAY: 
    1438       duration.daysAndTime = cast(double)(cast(int)duration.daysAndTime); 
    1439       break; 
    1440     case DatePart.HOUR: 
    1441       duration.daysAndTime = cast(int)(cast(double)duration.daysAndTime *  
    1442           HOUR_PER_DAY) / cast(double)HOUR_PER_DAY; 
    1443       break; 
    1444     case DatePart.MINUTE: 
    1445       duration.daysAndTime = cast(int)(cast(double)duration.daysAndTime *  
    1446           MIN_PER_DAY) / cast(double)MIN_PER_DAY; 
    1447       break; 
    1448     case DatePart.SECOND: 
    1449       duration.daysAndTime = cast(int)(cast(double)duration.daysAndTime *  
    1450           SEC_PER_DAY) / cast(double)SEC_PER_DAY; 
    1451       break; 
     1248      return date + count; 
    14521249    default: 
    14531250      throw new InvalidDatePartException(std.string.toString(cast(int)datePart) ~  
    14541251          " is an invalid date part"); 
    14551252  } 
    1456   return duration; 
     1253
     1254 
     1255 
     1256/** 
     1257 * Increment d_date date with a d_duration duration. 
     1258 * 
     1259 * Params: 
     1260 *  date =         A d_date date. 
     1261 *  duration =     A d_duration duration. 
     1262 * 
     1263 * Returns: A d_date date. 
     1264 */ 
     1265public d_date increment(d_date date, d_duration duration) { 
     1266  return addMonthsToDate(date, duration.months) + cast(int)duration.daysAndTime; 
     1267
     1268  
     1269 
     1270/** 
     1271 * Incremet a d_time times's date part datePart by a count. 
     1272 * 
     1273 * Params: 
     1274 *  time =         A d_time time. 
     1275 *  datePart =     A DatePart date part, in range HOUR..MILLISECOND. 
     1276 *  count =        A count of dateparts to increment. 
     1277 * 
     1278 * Returns: A d_time time. 
     1279 */ 
     1280public d_time increment(d_time time, DatePart datePart, int count) { 
     1281  switch (datePart) { 
     1282    case DatePart.HOUR: 
     1283      time += cast(d_time)(count * MSEC_PER_HOUR); 
     1284      break; 
     1285    case DatePart.MINUTE: 
     1286      time += cast(d_time)(count * MSEC_PER_MIN); 
     1287      break; 
     1288    case DatePart.SECOND: 
     1289      time += cast(d_time)(count * MSEC_PER_SEC); 
     1290      break; 
     1291    case DatePart.MILLISECOND: 
     1292      time += cast(d_time)count; 
     1293      break; 
     1294    default: 
     1295      throw new InvalidDatePartException(std.string.toString(cast(int)datePart) ~  
     1296          " is an invalid date part"); 
     1297  } 
     1298  return normTime(time); 
     1299
     1300 
     1301 
     1302/** 
     1303 * Increment d_time time with a d_duration duration. 
     1304 * 
     1305 * Params: 
     1306 *  time =         A d_time time. 
     1307 *  duration =     A d_duration duration. 
     1308 * 
     1309 * Returns: A d_time time. 
     1310 */ 
     1311public d_time increment(d_time time, d_duration duration) { 
     1312  time += cast(d_time)(duration.daysAndTime * MSEC_PER_DAY) % 
     1313      MSEC_PER_DAY; 
     1314  return normTime(time); 
     1315
     1316 
     1317 
     1318/** 
     1319 * Incremet a d_timestamp date/times's date part datePart by a count. 
     1320 * 
     1321 * Params: 
     1322 *  timestamp =    A d_timestamp date/time. 
     1323 *  datePart =     A DatePart date part, in range MILLENIA..MILLISECOND. 
     1324 *  count =        A count of dateparts to increment. 
     1325 * 
     1326 * Returns: A d_time time. 
     1327 */ 
     1328public d_timestamp increment(d_timestamp timestamp, DatePart datePart, int count) { 
     1329  if (datePart < DatePart.HOUR) { 
     1330    return toTimeStamp(increment(toDate(timestamp), datePart, count),  
     1331        toTime(timestamp)); 
     1332  } else { 
     1333    switch (datePart) { 
     1334      case DatePart.HOUR: 
     1335        timestamp += cast(d_timestamp)(count * (1.0 / HOUR_PER_DAY)); 
     1336        break; 
     1337      case DatePart.MINUTE: 
     1338        timestamp += cast(d_timestamp)(count * (1.0 / MIN_PER_DAY)); 
     1339        break; 
     1340      case DatePart.SECOND: 
     1341        timestamp += cast(d_timestamp)(count * (1.0 / SEC_PER_DAY)); 
     1342        break; 
     1343      case DatePart.MILLISECOND: 
     1344        timestamp += cast(d_timestamp)(count * (1.0 / MSEC_PER_DAY)); 
     1345        break; 
     1346      default: 
     1347        throw new InvalidDatePartException(std.string.toString(cast(int)datePart) ~  
     1348            " is an invalid date part"); 
     1349    } 
     1350    return timestamp; 
     1351  } 
     1352
     1353 
     1354 
     1355/** 
     1356 * Increment d_timestamp date/time with a d_duration duration. 
     1357 * 
     1358 * Params: 
     1359 *  timestamp =    A d_time time. 
     1360 *  duration =     A d_duration duration. 
     1361 * 
     1362 * Returns: A d_timestamp date/time. 
     1363 */ 
     1364public d_timestamp increment(d_timestamp timestamp, d_duration duration) { 
     1365  return increment(timestamp, DatePart.MONTH, duration.months) +  
     1366      cast(d_timestamp)duration.daysAndTime; 
    14571367} 
    14581368 
     
    15301440 
    15311441/** 
    1532  * Return the difference between two d_date dates as a d_duration duration. 
    1533  * 
    1534  * The difference can be extracted as an exact measure in days (default), and 
    1535  * optionally in relative measure by months and years. 
    1536  * 
    1537  * Params: 
    1538  *  fromDate =     A base d_date date. 
    1539  *  toDate =       A relative d_date date. 
    1540  *  relative =     If true duration is relative. 
    1541  * 
    1542  * Returns: A d_duration duration. 
    1543  */ 
    1544 public d_duration age(d_date fromDate, d_date toDate, bool relative = false) { 
    1545   d_duration duration; 
     1442 * Trunc a d_date date to a given date part. 
     1443 * 
     1444 * Params: 
     1445 *  date =         A d_date date. 
     1446 *  datePart =     A DatePart, in the range MILLENIA..WEEK. 
     1447 * 
     1448 * Returns: A d_date date. 
     1449 */ 
     1450public d_date truncate(d_date date, DatePart datePart) { 
     1451  int year, month, day; 
     1452  splitDate(date, year, month, day); 
     1453  switch (datePart) { 
     1454    case DatePart.MILLENIA: 
     1455      year = (year / 1000) * 1000; 
     1456      month = 1; 
     1457      day = 1; 
     1458      break; 
     1459    case DatePart.DECADE: 
     1460      year = (year / 10) * 10; 
     1461      month = 1; 
     1462      day = 1; 
     1463      break; 
     1464    case DatePart.YEAR: 
     1465      month = 1; 
     1466      day = 1; 
     1467      break; 
     1468    case DatePart.QUARTER: 
     1469      month = ((month - 1) / 3) * 3 + 1; 
     1470    case DatePart.MONTH: 
     1471      day = 1; 
     1472      break; 
     1473    case DatePart.WEEK: 
     1474      return date - weekDayOfDate(date); 
     1475    default: 
     1476      throw new InvalidDatePartException(std.string.toString(cast(int)datePart) ~  
     1477          " is an invalid date part"); 
     1478  } 
     1479  return toDate(year, month, day); 
     1480
     1481unittest { 
     1482  d_date d = toDate(2026, 10, 28); 
     1483  assert(truncate(d, DatePart.MILLENIA) == toDate(2000, 1, 1)); 
     1484  assert(truncate(d, DatePart.DECADE) == toDate(2020, 1, 1)); 
     1485  assert(truncate(d, DatePart.YEAR) == toDate(2026, 1, 1)); 
     1486  assert(truncate(d, DatePart.QUARTER) == toDate(2026, 10, 1)); 
     1487  assert(truncate(d, DatePart.MONTH) == toDate(2026, 10, 1)); 
     1488  assert(truncate(d, DatePart.WEEK) == toDate(2026, 10, 26));   
     1489
     1490 
     1491 
     1492/** 
     1493 * Trunc a d_time time to a given date part. 
     1494 * 
     1495 * Params: 
     1496 *  time =         A d_time date. 
     1497 *  datePart =     A DatePart, in the range HOUR..SECOND. 
     1498 * 
     1499 * Returns: A d_time time. 
     1500 */ 
     1501public d_time truncate(d_time time, DatePart datePart) { 
     1502  time = normTime(time); 
     1503  switch (datePart) { 
     1504    case DatePart.HOUR: 
     1505      return cast(d_time)(cast(int)(time / MSEC_PER_HOUR) * MSEC_PER_HOUR); 
     1506    case DatePart.MINUTE: 
     1507      return cast(d_time)(cast(int)(time / MSEC_PER_MIN) * MSEC_PER_MIN); 
     1508    case DatePart.SECOND: 
     1509      return cast(d_time)(cast(int)(time / MSEC_PER_SEC) * MSEC_PER_SEC); 
     1510    default: 
     1511      throw new InvalidDatePartException(std.string.toString(cast(int)datePart) ~  
     1512          " is an invalid date part"); 
     1513  } 
     1514
     1515unittest { 
     1516  d_time t = toTime(12, 13, 14, 15); 
     1517  assert(truncate(t, DatePart.SECOND) == toTime("12:13:14")); 
     1518  assert(truncate(t, DatePart.MINUTE) == toTime("12:13:00")); 
     1519  assert(truncate(t, DatePart.HOUR) == toTime("12:00:00")); 
     1520
     1521 
     1522 
     1523/** 
     1524 * Trunc a d_timestamp date to a given date part. 
     1525 * 
     1526 * Params: 
     1527 *  timestamp =         A d_timestamp date/time. 
     1528 *  datePart =     A DatePart, in the range MILLENIA..DAY, HOUR..SECOND. 
     1529 * 
     1530 * Returns: A d_timestamp date/time. 
     1531 */ 
     1532public d_timestamp truncate(d_timestamp timestamp, DatePart datePart) { 
     1533  if (datePart == DatePart.DAY) { 
     1534    return cast(d_timestamp)(cast(int)timestamp); 
     1535  } else { 
     1536    if (datePart < DatePart.HOUR) { 
     1537      return toTimeStamp(truncate(toDate(timestamp), datePart), 0); 
     1538    } else { 
     1539      return toTimeStamp(toDate(timestamp),  
     1540          truncate(toTime(timestamp), datePart)); 
     1541    } 
     1542  } 
     1543
     1544unittest { 
     1545  d_timestamp ts = toTimeStamp("2006-03-19 12:26:42"); 
     1546  assert(truncate(ts, DatePart.MINUTE) == toTimeStamp("2006-03-19 12:26:00")); 
     1547  assert(truncate(ts, DatePart.HOUR) == toTimeStamp("2006-03-19 12:00:00")); 
     1548  assert(truncate(ts, DatePart.DAY) == toTimeStamp("2006-03-19 00:00:00")); 
     1549  assert(truncate(ts, DatePart.WEEK) == toTimeStamp("2006-03-13 00:00:00")); 
     1550  assert(truncate(ts, DatePart.MONTH) == toTimeStamp("2006-03-01 00:00:00")); 
     1551  assert(truncate(ts, DatePart.QUARTER) == toTimeStamp("2006-01-01 00:00:00")); 
     1552  assert(truncate(ts, DatePart.YEAR) == toTimeStamp("2006-01-01 00:00:00")); 
     1553  assert(truncate(ts, DatePart.DECADE) == toTimeStamp("2000-01-01 00:00:00")); 
     1554  assert(truncate(ts, DatePart.MILLENIA) == toTimeStamp("2000-01-01 00:00:00")); 
     1555
     1556 
     1557 
     1558/** 
     1559 * Trunc an d_duration duration to a given date part. 
     1560 * 
     1561 * When truncing to dateparts in the range MILLENIA..MONTH all days will be 
     1562 * removed even if they theoretically could make up a larger date part. 
     1563 * 
     1564 * Params: 
     1565 *  duration =     An d_duration duration. 
     1566 *  datePart =     A DatePart, in the range MILLENIA..DAY, HOUR..SECOND. 
     1567 * 
     1568 * Returns: A d_timestamp date/time. 
     1569 */ 
     1570public d_duration truncate(d_duration duration, DatePart datePart) { 
     1571  if (datePart < DatePart.WEEK) { 
     1572    duration.daysAndTime = 0.0; 
     1573  } 
     1574  switch (datePart) { 
     1575    case DatePart.MILLENIA: 
     1576      duration.months = (duration.months / (12 * 1000)) * (12 *1000); 
     1577      break; 
     1578    case DatePart.DECADE: 
     1579      duration.months = (duration.months / (12 * 10)) * (12 *1); 
     1580      break; 
     1581    case DatePart.YEAR: 
     1582      duration.months = (duration.months / 12) * 12; 
     1583      break; 
     1584    case DatePart.QUARTER: 
     1585      duration.months = (duration.months / 3) * 3; 
     1586      break; 
     1587    case DatePart.MONTH: 
     1588      duration.months = (duration.months / (12 * 1000)) * (12 *1000); 
     1589      break; 
     1590    case DatePart.WEEK: 
     1591      duration.daysAndTime = cast(int)(duration.daysAndTime / 7) *  
     1592          cast(double)7.0; 
     1593      break; 
     1594    case DatePart.DAY: 
     1595      duration.daysAndTime = cast(double)(cast(int)duration.daysAndTime); 
     1596      break; 
     1597    case DatePart.HOUR: 
     1598      duration.daysAndTime = cast(int)(cast(double)duration.daysAndTime *  
     1599          HOUR_PER_DAY) / cast(double)HOUR_PER_DAY; 
     1600      break; 
     1601    case DatePart.MINUTE: 
     1602      duration.daysAndTime = cast(int)(cast(double)duration.daysAndTime *  
     1603          MIN_PER_DAY) / cast(double)MIN_PER_DAY; 
     1604      break; 
     1605    case DatePart.SECOND: 
     1606      duration.daysAndTime = cast(int)(cast(double)duration.daysAndTime *  
     1607          SEC_PER_DAY) / cast(double)SEC_PER_DAY; 
     1608      break; 
     1609    default: 
     1610      throw new InvalidDatePartException(std.string.toString(cast(int)datePart) ~  
     1611          " is an invalid date part"); 
     1612  } 
     1613  return duration; 
     1614
     1615 
     1616 
     1617/** 
     1618 * Create a string from a d_date date. 
     1619 * 
     1620 * Params: 
     1621 *  date =         A d_date date. 
     1622 *  format =       An optional format string, defaults to ISO 8601. 
     1623 * 
     1624 * Returns: The d_date date as a string. 
     1625 */ 
     1626public char[] toString(d_date date, char[] format = ISO_FORMAT_DATE) { 
     1627  assert(format == ISO_FORMAT_DATE); 
     1628  int year, month, day; 
     1629  splitDate(date, year, month, day); 
     1630  return std.string.format("%04d-%02d-%02d", year, month, day); 
     1631
     1632 
     1633 
     1634/** 
     1635 * Create a string from a d_time time. 
     1636 * 
     1637 * Params: 
     1638 *  time =         A d_time time. 
     1639 *  format =       An optional format string, defaults to ISO 8601. 
     1640 * 
     1641 * Returns: The d_time time as a string. 
     1642 */ 
     1643public char[] toString(d_time time, char[] format = ISO_FORMAT_TIME) { 
     1644  int hour, minute, second, millisecond; 
     1645 
     1646  assert(format == ISO_FORMAT_TIME); 
     1647 
     1648  splitTime(time, hour, minute, second, millisecond); 
     1649  return std.string.format("%02d:%02d:%02d", hour, minute, second); 
     1650
     1651  
     1652  
     1653/** 
     1654 * Create a string from a d_timestamp date/time. 
     1655 * 
     1656 * Params: 
     1657 *  timestamp =    A timestamnp_t date/time. 
     1658 *  format =       An optional format string, defaults to ISO 8601. 
     1659 * 
     1660 * Returns: The d_timestamp time as a string. 
     1661 */ 
     1662public char[] toString(d_timestamp timestamp,  
     1663    char[] format = ISO_FORMAT_TIMESTAMP) { 
     1664  assert(format == ISO_FORMAT_TIMESTAMP); 
    15461665   
    1547   if (!relative) { 
    1548     duration.daysAndTime = cast(double)(toDate - fromDate); 
    1549   } else { 
    1550     int fromYear, fromMonth, fromDay; 
    1551     int toYear, toMonth, toDay; 
    1552     splitDate(fromDate, fromYear, fromMonth, fromDay); 
    1553     splitDate(toDate, toYear, toMonth, toDay); 
    1554     duration.daysAndTime = cast(double)(toDay - fromDay); 
    1555     duration.months = (toYear * 12 + toMonth) - (fromYear * 12 + fromMonth); 
    1556   } 
    1557   return duration; 
    1558 
    1559  
    1560  
    1561 /** 
    1562  * Return the difference between two d_time times as a d_duration duration. 
    1563  * 
    1564  * Params: 
    1565  *  fromTime =     A base d_time time. 
    1566  *  toTime =       A relative d_time time. 
    1567  * 
    1568  * Returns: A d_duration duration. 
    1569  */ 
    1570 public d_duration age(d_time fromTime, d_time toTime) { 
    1571   d_duration duration; 
    1572   duration.daysAndTime = cast(double)(toTime - fromTime); 
    1573   return duration; 
    1574 
    1575  
    1576  
    1577 /** 
    1578  * Return the difference between two d_timestamp date/times as a d_duration  
    1579  * duration. 
    1580  * 
    1581  * The difference can be extracted as an exact measure in days (default), and 
    1582  * optionally in relative measure by months and years. 
    1583  * 
    1584  * Params: 
    1585  *  fromTimeStamp = A base d_timestamp date/time. 
    1586  *  toTimeStamp =  A relative d_timestamp date/time. 
    1587  *  relative =     If true duration is relative. 
    1588  * 
    1589  * Returns: A d_duration duration. 
    1590  */ 
    1591 public d_duration age(d_timestamp fromTimeStamp, d_timestamp toTimeStamp,  
    1592     bool relative = false) { 
    1593   d_duration duration; 
    1594  
    1595   duration = age(dateOfTimeStamp(fromTimeStamp), dateOfTimeStamp(toTimeStamp),  
    1596       relative); 
    1597   duration.daysAndTime += cast(double)(timeOfTimeStamp(toTimeStamp) -  
    1598       timeOfTimeStamp(fromTimeStamp)); 
    1599   return duration;  
     1666  return toString(toDate(timestamp), format[0..8]) ~ " " ~ 
     1667         toString(toTime(timestamp), format[9..$]); 
     1668
     1669  
     1670  
     1671/** 
     1672 * Create a string from a d_duration duration. 
     1673 * 
     1674 * Params: 
     1675 *  duration =     An d_duration duration. 
     1676 * 
     1677 * Returns: The d_duration duration as a string. 
     1678 */ 
     1679public char[] toString(d_duration duration) { 
     1680  assert(0); 
    16001681} 
    16011682 
  • branches/dateparse.d

    r50 r51  
    537537                            /* fractional Julian Day? */ 
    538538                            if (vald != int.min) { 
    539                 splitTime(timeOfTimeStamp(cast(d_timestamp)toDouble(field[pos..$])), 
     539                splitTimeTimeStamp(cast(d_timestamp)toDouble(field[pos..$]), 
    540540                    datetime.hour, datetime.minute, datetime.second, datetime.millisecond); 
    541541                                tmask |= maskTime();