Function parse
This function offers a generic date/time string Parser
which is able to parse
most known formats to represent a date and/or time.
This function attempts to be forgiving with regards to unlikely input formats,
returning a SysTime
object even for dates which are ambiguous. While other languages
have writing systems without Arabic numerals, the overwhelming majority of dates
are written with them. As such, this function does not work with other
number systems.
If an element of a date/time stamp is omitted, the following rules are applied:
- If AM or PM is left unspecified, a 24-hour clock is assumed, however, an hour on a 12-hour clock (0 <= hour <= 12) *must* be specified if AM or PM is specified.
- If a time zone is omitted, a SysTime is given with the timezone of the host machine.
Missing information is allowed, and what ever is given is applied on top of
the defaultDate
parameter, which defaults to January 1, 1 AD at midnight.
E.g. a string of "10:00 AM"
with a defaultDate
of
SysTime(Date(2016, 1, 1))
will yield SysTime(DateTime(2016, 1, 1, 10, 0, 0))
.
If your date string uses timezone names in place of UTC offsets, then timezone
information must be user provided, as there is no way to reliably get timezones
from the OS by abbreviation. But, the timezone will be properly set if an offset
is given. Timezone info and their abbreviations change constantly, so it's a
good idea to not rely on timezoneInfos
too much.
This function allocates memory and throws on the GC. In order to reduce GC allocations,
use a custom Parser
instance with a different allocator.
Prototype
SysTime parse(Range)(
Range timeString,
Flag!"ignoreTimezone" ignoreTimezone = No .ignoreTimezone,
const(TimeZone)[string] timezoneInfos = null,
Flag!"dayFirst" dayFirst = No .dayFirst,
Flag!"yearFirst" yearFirst = No .yearFirst,
Flag!"fuzzy" fuzzy = No .fuzzy,
SysTime defaultDate = SysTime(DateTime(1, 1, 1))
)
if (isForwardRange!Range && !isInfinite!Range && is(Unqual!(ElementEncodingType!Range) : char));
Parameters
Name | Description |
---|---|
timeString | A forward range with UTF-8 encoded elements containing a date/time stamp. |
ignoreTimezone | Set to false by default, time zones in parsed strings are ignored and a SysTime with the local time zone is returned. If timezone information is not important, setting this to true is slightly faster. |
timezoneInfos | Time zone names / aliases which may be present in the
string. This argument maps time zone names (and optionally offsets
from those time zones) to time zones. This parameter is ignored if
ignoreTimezone is set. |
dayFirst | Whether to interpret the first value in an ambiguous 3-integer date
(e.g. 01/05/09) as the day (true ) or month (false ). If
yearFirst is set to true, this distinguishes between YDM and
YMD. |
yearFirst | Whether to interpret the first value in an ambiguous 3-integer date (e.g. 01/05/09) as the year. If true, the first number is taken to be the year, otherwise the last number is taken to be the year. |
fuzzy | Whether to allow fuzzy parsing, allowing for string like "Today is
January 1, 2047 at 8:21:00AM". |
defaultDate | The date to apply the given information on top of. Defaults to January 1st, 1 AD |
Returns
A SysTime object representing the parsed string
Throws
ConvException
will be thrown for invalid string or unknown string format
Throws
TimeException
if the date string is successfully parsed but the created
date would be invalid
Throws
ConvOverflowException
if one of the numbers in the parsed date exceeds
float.max
Example
immutable brazilTime = new SimpleTimeZone(dur!"seconds"(-10_800));
const(TimeZone)[string] timezones = ["BRST" : brazilTime];
immutable parsed = parse("Thu Sep 25 10:36:28 BRST 2003", No .ignoreTimezone, timezones);
// SysTime opEquals ignores timezones
assert(parsed == SysTime(DateTime(2003, 9, 25, 10, 36, 28)));
assert(parsed .timezone == brazilTime);
assert(parse(
"2003 10:36:28 BRST 25 Sep Thu",
No .ignoreTimezone,
timezones
) == SysTime(DateTime(2003, 9, 25, 10, 36, 28)));
assert(parse("Thu Sep 25 10:36:28") == SysTime(DateTime(1, 9, 25, 10, 36, 28)));
assert(parse("20030925T104941") == SysTime(DateTime(2003, 9, 25, 10, 49, 41)));
assert(parse("2003-09-25T10:49:41") == SysTime(DateTime(2003, 9, 25, 10, 49, 41)));
assert(parse("10:36:28") == SysTime(DateTime(1, 1, 1, 10, 36, 28)));
assert(parse("09-25-2003") == SysTime(DateTime(2003, 9, 25)));
Example
Apply information on top of defaultDate
assert("10:36:28" .parse(No .ignoreTimezone, null, No .dayFirst, No .yearFirst,
No .fuzzy, SysTime(DateTime(2016, 3, 15)))
== SysTime(DateTime(2016, 3, 15, 10, 36, 28)));
assert("August 07" .parse(No .ignoreTimezone, null, No .dayFirst, No .yearFirst,
No .fuzzy, SysTime(DateTime(2016, 1, 1)))
== SysTime(Date(2016, 8, 7)));
assert("2000" .parse(No .ignoreTimezone, null, No .dayFirst, No .yearFirst,
No .fuzzy, SysTime(DateTime(2016, 3, 1)))
== SysTime(Date(2000, 3, 1)));
Example
Custom allocators
import std .experimental .allocator .mallocator;
auto customParser = new Parser!Mallocator(new ParserInfo());
assert(customParser .parse("2003-09-25T10:49:41") ==
SysTime(DateTime(2003, 9, 25, 10, 49, 41)));
Example
Exceptions
import std .exception : assertThrown;
import std .conv : ConvException;
assertThrown!ConvException(parse(""));
assertThrown!ConvException(parse("AM"));
assertThrown!ConvException(parse("The quick brown fox jumps over the lazy dog"));
assertThrown!TimeException(parse("Feb 30, 2007"));
assertThrown!TimeException(parse("Jan 20, 2015 PM"));
assertThrown!ConvException(parse("13:44 AM"));
assertThrown!ConvException(parse("January 25, 1921 23:13 PM"));
Example
Custom parser info allows for international time representation
class RusParserInfo : ParserInfo
{
this()
{
super(false, false);
monthsAA = ParserInfo .convert([
["янв", "Январь"],
["фев", "Февраль"],
["мар", "Март"],
["апр", "Апрель"],
["май", "Май"],
["июн", "Июнь"],
["июл", "Июль"],
["авг", "Август"],
["сен", "Сентябрь"],
["окт", "Октябрь"],
["ноя", "Ноябрь"],
["дек", "Декабрь"]
]);
}
}
auto rusParser = new Parser!GCAllocator(new RusParserInfo());
immutable parsedTime = rusParser .parse("10 Сентябрь 2015 10:20");
assert(parsedTime == SysTime(DateTime(2015, 9, 10, 10, 20)));