123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115(*
* Copyright (C) 2006-2009 Citrix Systems Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; version 2.1 only. with the special
* exception on linking described in file LICENSE.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*)(* ==== RFC822 ==== *)typerfc822=stringletmonths=[|"Jan";"Feb";"Mar";"Apr";"May";"Jun";"Jul";"Aug";"Sep";"Oct";"Nov";"Dec"|]letdays=[|"Sun";"Mon";"Tue";"Wed";"Thu";"Fri";"Sat"|]letrfc822_of_floatx=lettime=Unix.gmtimexinPrintf.sprintf"%s, %d %s %d %02d:%02d:%02d GMT"days.(time.Unix.tm_wday)time.Unix.tm_mdaymonths.(time.Unix.tm_mon)(time.Unix.tm_year+1900)time.Unix.tm_hourtime.Unix.tm_mintime.Unix.tm_secletrfc822_to_stringx=x(* ==== ISO8601/RFC3339 ==== *)typeprint_timezone=Empty|TZofstring(* we must store the print_type with iso8601 to handle the case where the local time zone is UTC *)typeiso8601=Ptime.date*Ptime.time*print_timezoneletutc=TZ"Z"letof_dtprint_typedt=let(date,time)=dtin(date,time,print_type)letto_dt(date,time,_)=(date,time)letbest_effort_iso8601_to_rfc3339x=(* (a) add dashes
* (b) add UTC tz if no tz provided *)letx=tryScanf.sscanfx"%04d%02d%02dT%s"(funymondrest->Printf.sprintf"%04d-%02d-%02dT%s"ymondrest)with_->xinlettz=tryScanf.sscanfx"%04d-%02d-%02dT%02d:%02d:%02d%s"(fun______tz->Sometz)with_->Noneinmatchtzwith|None|Some""->(* the caller didn't specify a tz. we must try to add one so that ptime can at least attempt to parse *)(Printf.sprintf"%sZ"x,Empty)|Sometz->(x,TZtz)letof_stringx=let(rfc3339,print_timezone)=best_effort_iso8601_to_rfc3339xinmatchPtime.of_rfc3339rfc3339|>Ptime.rfc3339_error_to_msgwith|Error(`Msge)->invalid_arg(Printf.sprintf"date.ml:of_string: %s"x)|Ok(t,tz,_)->matchtzwith|None|Some0->Ptime.to_date_timet|>of_dtprint_timezone|Some_->invalid_arg(Printf.sprintf"date.ml:of_string: %s"x)letto_string((y,mon,d),((h,min,s),_),print_type)=matchprint_typewith|TZtz->Printf.sprintf"%04i%02i%02iT%02i:%02i:%02i%s"ymondhminstz|Empty->Printf.sprintf"%04i%02i%02iT%02i:%02i:%02i"ymondhminsletto_ptime_tt=matchto_dtt|>Ptime.of_date_timewith|Somet->t|None->let(_,(_,offset),_)=tininvalid_arg(Printf.sprintf"date.ml:to_t: dt='%s', offset='%i' is invalid"(to_stringt)offset)letof_floats=matchPtime.of_float_sswith|None->invalid_arg(Printf.sprintf"date.ml:of_float: %f"s)|Somet->Ptime.to_date_timet|>of_dtutcletto_floatt=to_ptime_tt|>Ptime.to_float_slet_localtimecurrent_tz_offsett=lettz_offset_s=current_tz_offset|>Option.value~default:0inletlocaltime=t|>Ptime.to_date_time~tz_offset_s|>of_dtEmptyinlet(_,(_,localtime_offset),_)=localtimeiniflocaltime_offset<>tz_offset_stheninvalid_arg(Printf.sprintf"date.ml:_localtime: offsets don't match. offset='%i', t='%s'"tz_offset_s(Ptime.to_rfc3339t));localtimelet_localtime_stringcurrent_tz_offsett=_localtimecurrent_tz_offsett|>to_stringletlocaltime()=_localtime(Ptime_clock.current_tz_offset_s())(Ptime_clock.now())letassert_utc_=()letnever=of_float0.0leteqxy=x=y