1 /****************************************************************************** 2 3 Parses a HTTP compliant date/time string and converts it to the 4 UNIX time value 5 6 Copyright: 7 Copyright (c) 2009-2016 dunnhumby Germany GmbH. 8 All rights reserved. 9 10 License: 11 Boost Software License Version 1.0. See LICENSE_BOOST.txt for details. 12 Alternatively, this file may be distributed under the terms of the Tango 13 3-Clause BSD License (see LICENSE_BSD.txt for details). 14 15 ******************************************************************************/ 16 17 module ocean.net.http.time.HttpTimeParser; 18 19 20 import ocean.meta.types.Qualifiers; 21 22 import TimeStamp = ocean.text.convert.TimeStamp: rfc1123, rfc850, asctime; 23 24 import ocean.time.Time: Date, TimeOfDay; 25 26 import core.stdc.time: time_t, tm; 27 import core.sys.posix.time: timegm; 28 29 version (unittest) import ocean.core.Test; 30 31 /****************************************************************************** 32 33 Parses timestamp, which is expected to be a HTTP compliant date/time string, 34 and converts it to the UNIX time value. 35 36 @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3 37 38 Params: 39 timestamp = HTTP compliant date/time string 40 t = resulting UNIX time value; changed only if the return value 41 is true 42 43 Returns: 44 true if the conversion succeeded or false on parse error or invalid 45 date/time value 46 47 ******************************************************************************/ 48 49 bool parse ( cstring timestamp, ref time_t t ) 50 { 51 Date date; 52 TimeOfDay tod; 53 54 bool ok = TimeStamp.rfc1123(timestamp, tod, date) != 0; 55 56 if (!ok) 57 { 58 ok = TimeStamp.rfc850(timestamp, tod, date) != 0; 59 } 60 61 if (!ok) 62 { 63 ok = TimeStamp.asctime(timestamp, tod, date) != 0; 64 } 65 66 if (ok) 67 { 68 tm timeval; 69 70 with (timeval) 71 { 72 tm_sec = tod.seconds; 73 tm_min = tod.minutes; 74 tm_hour = tod.hours; 75 tm_mday = date.day; 76 tm_mon = date.month - 1; 77 tm_year = date.year - 1900; 78 } 79 80 time_t t_ = timegm(&timeval); 81 82 ok = t_ >= 0; 83 84 if (ok) 85 { 86 t = t_; 87 } 88 } 89 90 return ok; 91 } 92 93 /****************************************************************************** 94 95 Using http://www.epochconverter.com/ as reference. 96 97 ******************************************************************************/ 98 99 unittest 100 { 101 static immutable time_t T = 352716457; 102 103 time_t t; 104 105 bool ok = parse("Fri, 06 Mar 1981 08:47:37 GMT", t); 106 test (ok); 107 test (t == T); 108 109 ok = parse("Friday, 06-Mar-81 08:47:37 GMT", t); 110 test (ok); 111 test (t == T); 112 113 ok = parse("Fri Mar 6 08:47:37 1981", t); 114 test (ok); 115 test (t == T); 116 }