Thread overview
Re: SysTime.fromISOString
May 13, 2017
Jonathan M Davis
May 13, 2017
Russel Winder
May 13, 2017
Jonathan M Davis
May 13, 2017
Russel Winder
May 13, 2017
Russel Winder
May 13, 2017
Jonathan M Davis
May 13, 2017
Jonathan M Davis
May 13, 2017
Russel Winder
May 13, 2017
Russel Winder
May 13, 2017
On Saturday, May 13, 2017 07:33:35 Russel Winder via Digitalmars-d-learn wrote:
> A priori I thought 2015 was a perfectly valid ISO8601 date-time specification. It appears that SysTime.fromISOString disagrees:
>
> core.time.TimeException@/usr/include/d/std/datetime.d(8553): Invalid
> ISO String: 2015
>
> So am I right or wrong. https://en.wikipedia.org/wiki/ISO_8601https://en.wikipedia.org/wiki/ISO_8 601

The ISO representation of a date is YYYYMMDD, and the extended ISO representation is YYYY-MM-DD. YYYY would be a truncated representation. The standard has language such as "If, by agreement, truncated representations are used" to talk about truncated representations, but it's not part of the actual, standard string representation. It's just giving guidance on what applications should do if they decide to not use the full string representation when communicating with one another, and it's not expected that an application that supports the standard would support truncated representations. It's only "by agreement," between two applications, not standard. std.datetime only supports the full, standard string representation, and for SysTime, that also includes the time, not just the date. std.datetime.Date would be the closest, but it represents a date, not just a year, so it's YYYYMMDD or YYYY-MM-DD. If you want to pass a string to SysTime.fromISOString, it's going to need to be YYYYMMDDTHHMMSS (optionally with fractional seconds and a time zone).

And really, there isn't much useful that can be done with a SysTime that was constructed from just a year anyway. The best SysTime could do would be to assume you meant 2015-01-01T00:00:00. It operates on the system time in hecto-nanoseconds and really isn't meant be operating on dates (that's what Date and DateTime are for). Converting 2015 to a SysTime with no information would be like trying to construct a time_t in C with just 2015. That usually doesn't make much sense. Nothing in std.datetime operates simply on a year. The closest that you're going to get to that is Date.

Regardless, if you know that you're just dealing with a year, and that's it, you can just call to!int on it and pass it to the constructor of SysTime, DateTime, or Date (depending on which you want to use) with whatever values you want to set for the month, day, etc. Using a function like fromISOString would just be overkill if all you have is a year, even if it did accept truncated representations. But the truncated representations are not required by the standard, so they're not supported.

- Jonathan M Davis

May 13, 2017
On Sat, 2017-05-13 at 01:52 -0700, Jonathan M Davis via Digitalmars-d- learn wrote:
> […]
> The ISO representation of a date is YYYYMMDD, and the extended ISO
> representation is YYYY-MM-DD. YYYY would be a truncated
> representation. The
> standard has language such as "If, by agreement, truncated
> representations
> are used" to talk about truncated representations, but it's not part
> of the
> actual, standard string representation. It's just giving guidance on
> what
> applications should do if they decide to not use the full string
> representation when communicating with one another, and it's not
> expected
> that an application that supports the standard would support
> truncated
> representations. It's only "by agreement," between two applications,
> not
> standard. std.datetime only supports the full, standard string
> representation, and for SysTime, that also includes the time, not
> just the
> date. std.datetime.Date would be the closest, but it represents a
> date, not
> just a year, so it's YYYYMMDD or YYYY-MM-DD. If you want to pass a
> string to
> SysTime.fromISOString, it's going to need to be
> YYYYMMDDTHHMMSS (optionally
> with fractional seconds and a time zone).

My reading is that YYYY-MM is an allowed form: I was wrong to suggest YYYY was allowed.

For times hh:mm is allowed as well as hh:mm:ss.

fromIsoString should allow for YYYYMMDDTHHMMSS and YYYY-MM-DDThh:mm:ss shouldn't it?

> And really, there isn't much useful that can be done with a SysTime
> that was
> constructed from just a year anyway. The best SysTime could do would
> be to
> assume you meant 2015-01-01T00:00:00. It operates on the system time
> in
> hecto-nanoseconds and really isn't meant be operating on dates
> (that's what
> Date and DateTime are for). Converting 2015 to a SysTime with no
> information
> would be like trying to construct a time_t in C with just 2015. That
> usually
> doesn't make much sense. Nothing in std.datetime operates simply on a
> year.
> The closest that you're going to get to that is Date.

I agree I need to construct a Date or  DateTime from the string and
then a SysTime from that. I was just being lazy earlier.

> Regardless, if you know that you're just dealing with a year, and
> that's it,
> you can just call to!int on it and pass it to the constructor of
> SysTime,
> DateTime, or Date (depending on which you want to use) with whatever
> values
> you want to set for the month, day, etc. Using a function like
> fromISOString
> would just be overkill if all you have is a year, even if it did
> accept
> truncated representations. But the truncated representations are not
> required by the standard, so they're not supported.

Indeed. However I believe the standard defines more than is accepted. The code:

auto newDate = Date.fromISOString(date_buffer);

leads to:

core.time.TimeException@/usr/include/d/std/datetime.d(12932): Invalid ISO String: 2015-05-10

I'd suggest 2015-05-10 is a perfectly good ISO8601 compliant date and so highlights a bug/

-- 
Russel. ============================================================================= Dr Russel Winder      t: +44 20 7585 2200   voip: sip:russel.winder@ekiga.net 41 Buckmaster Road    m: +44 7770 465 077   xmpp: russel@winder.org.uk London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder

May 13, 2017
On Saturday, May 13, 2017 12:06:57 Russel Winder via Digitalmars-d-learn wrote:
> On Sat, 2017-05-13 at 01:52 -0700, Jonathan M Davis via Digitalmars-d-
> learn wrote:
> My reading is that YYYY-MM is an allowed form: I was wrong to suggest
> YYYY was allowed.

YYYY-MM is still truncated and therefore only permitted if applications agree to it.

> For times hh:mm is allowed as well as hh:mm:ss.

Rereading the spec, yes, HH:MM is permitted instead of HH:MM:SS, but HH is not, and any truncation of YYYY-MM-DD is considered a truncation and therefore only permitted if the applications involved agree to it.

So, arguably fromISOString and fromISOExtString should be changed to allow HHMM and HH:MM respectively but not HH, YYYY-MM, YYYYMM, or YYYY.

> fromIsoString should allow for YYYYMMDDTHHMMSS and YYYY-MM-DDThh:mm:ss shouldn't it?

YYYYMMDDTHHMMSS is the ISO basic format, and YYYY-MM-DDTHH:MM:SS is the ISO extended format (so, they're both from the same standard, but they're not the same format). fromISOString handles the ISO basic format, and fromISOExtString handles the ISO extended format.

> > Regardless, if you know that you're just dealing with a year, and
> > that's it,
> > you can just call to!int on it and pass it to the constructor of
> > SysTime,
> > DateTime, or Date (depending on which you want to use) with whatever
> > values
> > you want to set for the month, day, etc. Using a function like
> > fromISOString
> > would just be overkill if all you have is a year, even if it did
> > accept
> > truncated representations. But the truncated representations are not
> > required by the standard, so they're not supported.
>
> Indeed. However I believe the standard defines more than is accepted. The code:
>
> auto newDate = Date.fromISOString(date_buffer);
>
> leads to:
>
> core.time.TimeException@/usr/include/d/std/datetime.d(12932): Invalid ISO
> String: 2015-05-10
>
> I'd suggest 2015-05-10 is a perfectly good ISO8601 compliant date and so highlights a bug/

fromISOString is throwing, because you're giving it the extended format. For that, you need to use fromISOExtString.

- Jonathan M Davis

May 13, 2017
And this seems awkward:


	auto date = Clock.currTime();
	auto date_buffer = date.toISOString();
…
	try {
		date = SysTime.fromISOString(date_buffer);
	} catch (DateTimeException dte) {
		try {
			date =
SysTime(DateTime.fromISOString(date_buffer));
		} catch (DateTimeException ddttee) {
			date =
SysTime(Date.fromISOString(date_buffer));
		}
	}

Even though it works, well with 20150510 if not 2015-05-10.

I suspect I am doing it wrong. :-)

-- 
Russel. ============================================================================= Dr Russel Winder      t: +44 20 7585 2200   voip: sip:russel.winder@ekiga.net 41 Buckmaster Road    m: +44 7770 465 077   xmpp: russel@winder.org.uk London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder

May 13, 2017
On Sat, 2017-05-13 at 04:24 -0700, Jonathan M Davis via Digitalmars-d- learn wrote:
> […]
> 
> YYYY-MM is still truncated and therefore only permitted if
> applications
> agree to it.

But didn't that come is as standard in the 2000 standard along with -- MM-DD for yearless date?

> > For times hh:mm is allowed as well as hh:mm:ss.
> 
> Rereading the spec, yes, HH:MM is permitted instead of HH:MM:SS, but
> HH is
> not, and any truncation of YYYY-MM-DD is considered a truncation and
> therefore only permitted if the applications involved agree to it.

I'm still going to fight for YYYY-MM, but not to the extent of buying the latest standard document from ISO!

> So, arguably fromISOString and fromISOExtString should be changed to
> allow
> HHMM and HH:MM respectively but not HH, YYYY-MM, YYYYMM, or YYYY.
> 
> > fromIsoString should allow for YYYYMMDDTHHMMSS and YYYY-MM-
> > DDThh:mm:ss
> > shouldn't it?
> 
> YYYYMMDDTHHMMSS is the ISO basic format, and YYYY-MM-DDTHH:MM:SS is
> the ISO
> extended format (so, they're both from the same standard, but they're
> not
> the same format). fromISOString handles the ISO basic format, and
> fromISOExtString handles the ISO extended format.

OK, we have my error, two different calls. Of course this means for a string from the users you have to attempt a parse in one format and then on exception try the other format. From a programmer perspective trying to build a SysTime from user input is really awkward. Unless I am missing a magic parse function.

> > > Regardless, if you know that you're just dealing with a year, and
> > > that's it,
> > > you can just call to!int on it and pass it to the constructor of
> > > SysTime,
> > > DateTime, or Date (depending on which you want to use) with
> > > whatever
> > > values
> > > you want to set for the month, day, etc. Using a function like
> > > fromISOString
> > > would just be overkill if all you have is a year, even if it did
> > > accept
> > > truncated representations. But the truncated representations are
> > > not
> > > required by the standard, so they're not supported.
> > 
> > Indeed. However I believe the standard defines more than is
> > accepted.
> > The code:
> > 
> > auto newDate = Date.fromISOString(date_buffer);
> > 
> > leads to:
> > 
> > core.time.TimeException@/usr/include/d/std/datetime.d(12932):
> > Invalid ISO
> > String: 2015-05-10
> > 
> > I'd suggest 2015-05-10 is a perfectly good ISO8601 compliant date
> > and
> > so highlights a bug/
> 
> fromISOString is throwing, because you're giving it the extended
> format. For
> that, you need to use fromISOExtString.

From the perspective of someone trying to parse "Input ISO format string" really, really awkward. I do not want to use Vladimirs parse since it copes with to many formats, I just want IS8601 compliant parse (hence not using parse822Format.

You have pointed out why I was getting the error, but I think you can accept that the tools that are there for converting strings to IS dates need a bit of amendment to make them easy for programmers to work with.

-- 
Russel. ============================================================================= Dr Russel Winder      t: +44 20 7585 2200   voip: sip:russel.winder@ekiga.net 41 Buckmaster Road    m: +44 7770 465 077   xmpp: russel@winder.org.uk London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder

May 13, 2017
On Saturday, May 13, 2017 12:31:38 Russel Winder via Digitalmars-d-learn wrote:
> And this seems awkward:
>
>
>   auto date = Clock.currTime();
>   auto date_buffer = date.toISOString();
> >   try {
>       date = SysTime.fromISOString(date_buffer);
>   } catch (DateTimeException dte) {
>       try {
>           date =
> SysTime(DateTime.fromISOString(date_buffer));
>       } catch (DateTimeException ddttee) {
>           date =
> SysTime(Date.fromISOString(date_buffer));
>       }
>   }
>
> Even though it works, well with 20150510 if not 2015-05-10.
>
> I suspect I am doing it wrong. :-)

Well, Clock.currTime() gives you a SysTime, not a Date. So, your date variable is a SysTime, and date_buffer is going to be something like "20170513T123138.12392". Calling SysTime.fromISOString will therefore work on that without throwing, and calling either Date.fromISOString or DateTime.fromISOString is going to throw, because Date doesn't support the time (just the date), and DateTime doesn't support the fractional seconds or a time zone (though you wouldn't currently get a time zone in this case, because I still need to fix it so that LocalTime gives you a time zone for to*String - if the time zone isn't there, then local time is assumed, so what it's doing right now is technically correct, but it's error-prone).

std.datetime's from*String functions are designed to be fairly strict about parsing, so you need to be fairly sure of what kind of string you're dealing with. Certainly, you need to know whether you're dealing with the basic ISO format or the extended ISO format, and you need to know which pieces are going to be in the string. If it's going to be just the date (e.g. 2012-12-21), then you're going to need to use Date. If it's going to be just the time (e.g. 04:19:22), then you're going to need to use TimeOfDay. If it's going to be the date and the time (e.g. 2012-12-21T04:19:22), then you can use either SysTime or DateTime, but if it's the data and the time and includes the fractional seconds and/or a time zone (e.g. 2012-12-21T:04:19:22.0002, 2012-12-21T:04:19:22+08:00, or 2012-12-21T:04:19:22.0002+08:00), then you'll need to use SysTime, because DateTime does not support either the fractional seconds or a time zone.

Each type is expecting a string with the pieces (date, time, fractional seconds, and time zone) that it supports and that they'll all be there. The only stuff that's optional is the fractional seconds and time zone when dealing with SysTime, because the spec does not require that they be there.

If you were trying to be lax with the parsing and accept the various combinations of what's legal, then you'd be stuck doing something like

SysTime st;
try
{
    // If it's YYYY-MM-DDTHH:MM:SS.FFFFFFFZ
    // If it's YYYY-MM-DDTHH:MM:SS.FFFFFFZ
    // If it's YYYY-MM-DDTHH:MM:SS.FFFFFZ
    // If it's YYYY-MM-DDTHH:MM:SS.FFFFZ
    // If it's YYYY-MM-DDTHH:MM:SS.FFFZ
    // If it's YYYY-MM-DDTHH:MM:SS.FFZ
    // If it's YYYY-MM-DDTHH:MM:SS.FZ
    // or      YYYY-MM-DDTHH:MM:SSZ
    // or      YYYY-MM-DDTHH:MM:SS.FFFFFFF
    // or      YYYY-MM-DDTHH:MM:SS.FFFFFF
    // or      YYYY-MM-DDTHH:MM:SS.FFFFF
    // or      YYYY-MM-DDTHH:MM:SS.FFFF
    // or      YYYY-MM-DDTHH:MM:SS.FFF
    // or      YYYY-MM-DDTHH:MM:SS.FF
    // or      YYYY-MM-DDTHH:MM:SS.F
    // or      YYYY-MM-DDTHH:MM:SS
    st = SysTime.fromISOExtString(str);
}
catch(DateTimeException)
{
    try
    {
        // If it's just YYYY-MM-DD
        st = SysTime(Date.fromISOExtString(str));
    }
    catch(DateTimeException)
    {
        // If it's just HH:MM:SS
        st = SysTime(Date.init, TimeOfDay.fromISOExtString(str));
    }
}

But that would be downright bizarre in the case where it was just HH:MM:SS, because then you'd end up with a SysTime on January 1st, 1 A.D. And while getting just the date is less awkward, it's still kind off to then operate on that as a SysTime. The time would always be at midnight.

Really, just parsing an "ISO formatted string" and allowing either the date or time to be optional doesn't make much sense to me. That implies that you don't really know what it's for, since the meaning of something that is just a date and the meaning of something that is just a time are completely different.

Regardless, std.datetime was designed with the idea that you knew whether you were dealing with a date, a time, or both a date and a time when dealing with ISO formatted strings.

- Jonathan M Davis


May 13, 2017
On Saturday, May 13, 2017 12:56:31 Russel Winder via Digitalmars-d-learn wrote:
> On Sat, 2017-05-13 at 04:24 -0700, Jonathan M Davis via Digitalmars-d-
>
> learn wrote:
> > […]
> >
> > YYYY-MM is still truncated and therefore only permitted if
> > applications
> > agree to it.
>
> But didn't that come is as standard in the 2000 standard along with -- MM-DD for yearless date?
>
> > > For times hh:mm is allowed as well as hh:mm:ss.
> >
> > Rereading the spec, yes, HH:MM is permitted instead of HH:MM:SS, but
> > HH is
> > not, and any truncation of YYYY-MM-DD is considered a truncation and
> > therefore only permitted if the applications involved agree to it.
>
> I'm still going to fight for YYYY-MM, but not to the extent of buying the latest standard document from ISO!

As I said, per the standard, YYYY-MM is a truncated representation, and applications can agree that they'll support it, but it's not required. All of the sections on truncated representations have language such as "If, by agreement, truncated representations are used". Each of the from*String functions are quite specific about what they support. The only portion that's optional that std.datetime supports is the fractional seconds.

It looks like I need to make HHMM and HH:MM supported to completely follow the spec (since that's considered a reduction in precision rather than a truncation and is not listed as optional), but all of the various truncations are considered optional by the spec and therefore not supported by std.datetime (and supporting them risks problems with ambiguity - e.g. you can't distinguish YYYY from HHMM).

> > So, arguably fromISOString and fromISOExtString should be changed to
> > allow
> > HHMM and HH:MM respectively but not HH, YYYY-MM, YYYYMM, or YYYY.
> >
> > > fromIsoString should allow for YYYYMMDDTHHMMSS and YYYY-MM-
> > > DDThh:mm:ss
> > > shouldn't it?
> >
> > YYYYMMDDTHHMMSS is the ISO basic format, and YYYY-MM-DDTHH:MM:SS is
> > the ISO
> > extended format (so, they're both from the same standard, but they're
> > not
> > the same format). fromISOString handles the ISO basic format, and
> > fromISOExtString handles the ISO extended format.
>
> OK, we have my error, two different calls. Of course this means for a string from the users you have to attempt a parse in one format and then on exception try the other format. From a programmer perspective trying to build a SysTime from user input is really awkward. Unless I am missing a magic parse function.

> > fromISOString is throwing, because you're giving it the extended
> > format. For
> > that, you need to use fromISOExtString.
>
> From the perspective of someone trying to parse "Input ISO format string" really, really awkward. I do not want to use Vladimirs parse since it copes with to many formats, I just want IS8601 compliant parse (hence not using parse822Format.
>
> You have pointed out why I was getting the error, but I think you can accept that the tools that are there for converting strings to IS dates need a bit of amendment to make them easy for programmers to work with.

The expectation is that you know which format you're dealing with. std.datetime is not written with the idea that you're dealing with a string with an arbitrary date/time format, and it's going to figure out what it is. It's written with the idea that you know exactly which format the string is in, and it converts the string based on the rules for that format. The ISO basic format and ISO extended format are two different formats. And in my experience, when applications are exchanging information via ISO strings, it's well-defined which format they're going to use. If you're actually dealing with a situation where it's not well-defined, then yes, using std.datetime becomes more painful.

A magic parsing function which supported both the ISO basic format and the ISO extended format as well as the various truncated versions of those formats could be written, but it would be very error-prone and in at least some situations, it would be ambiguous, meaning that it could easily make the wrong choice. Using the truncated forms really only works when two applications have agreed on exactly how they're going to handle that, which is likely the reason that the spec says that they're there for if applications agree upon them rather than requiring that an application that supports either the ISO basic format or the ISO extended format supports the truncated versions.

- Jonathan M Davis


May 13, 2017
On Sat, 2017-05-13 at 05:30 -0700, Jonathan M Davis via Digitalmars-d- learn wrote:
> 
> […]

I can see I am not going to win the YYYY-MM discussion so I'll stand down. Until I have read the latest version of the standard – I remain sure this is a reduced accuracy not a truncated representation. But I could just be wrong.

> The expectation is that you know which format you're dealing with.
> std.datetime is not written with the idea that you're dealing with a
> string
> with an arbitrary date/time format, and it's going to figure out what
> it is.
> It's written with the idea that you know exactly which format the
> string is
> in, and it converts the string based on the rules for that format.
> The ISO
> basic format and ISO extended format are two different formats. And
> in my
> experience, when applications are exchanging information via ISO
> strings,
> it's well-defined which format they're going to use. If you're
> actually
> dealing with a situation where it's not well-defined, then yes, using
> std.datetime becomes more painful.

I have just done the obvious cascaded try/catch block to try from the most specific to the least specific, but I'll drop that here as you have got stuck in to dealing with in the other email. (Which is great, thanks for taking the time.)

> A magic parsing function which supported both the ISO basic format
> and the
> ISO extended format as well as the various truncated versions of
> those
> formats could be written, but it would be very error-prone and in at
> least
> some situations, it would be ambiguous, meaning that it could easily
> make
> the wrong choice. Using the truncated forms really only works when
> two
> applications have agreed on exactly how they're going to handle that,
> which
> is likely the reason that the spec says that they're there for if
> applications agree upon them rather than requiring that an
> application that
> supports either the ISO basic format or the ISO extended format
> supports the
> truncated versions.

I think my situation is not the general case so actually I have no problem. But I shall shift this to the other thread.

-- 
Russel. ============================================================================= Dr Russel Winder      t: +44 20 7585 2200   voip: sip:russel.winder@ekiga.net 41 Buckmaster Road    m: +44 7770 465 077   xmpp: russel@winder.org.uk London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder

May 13, 2017
On Sat, 2017-05-13 at 05:03 -0700, Jonathan M Davis via Digitalmars-d- learn wrote:
> 
[…]
> SysTime st;
> try
> {
>     // If it's YYYY-MM-DDTHH:MM:SS.FFFFFFFZ
>     // If it's YYYY-MM-DDTHH:MM:SS.FFFFFFZ
>     // If it's YYYY-MM-DDTHH:MM:SS.FFFFFZ
>     // If it's YYYY-MM-DDTHH:MM:SS.FFFFZ
>     // If it's YYYY-MM-DDTHH:MM:SS.FFFZ
>     // If it's YYYY-MM-DDTHH:MM:SS.FFZ
>     // If it's YYYY-MM-DDTHH:MM:SS.FZ
>     // or      YYYY-MM-DDTHH:MM:SSZ
>     // or      YYYY-MM-DDTHH:MM:SS.FFFFFFF
>     // or      YYYY-MM-DDTHH:MM:SS.FFFFFF
>     // or      YYYY-MM-DDTHH:MM:SS.FFFFF
>     // or      YYYY-MM-DDTHH:MM:SS.FFFF
>     // or      YYYY-MM-DDTHH:MM:SS.FFF
>     // or      YYYY-MM-DDTHH:MM:SS.FF
>     // or      YYYY-MM-DDTHH:MM:SS.F
>     // or      YYYY-MM-DDTHH:MM:SS
>     st = SysTime.fromISOExtString(str);
> }
> catch(DateTimeException)
> {
>     try
>     {
>         // If it's just YYYY-MM-DD
>         st = SysTime(Date.fromISOExtString(str));
>     }

A variation on this is where I have gone, so that you are not telling me I am doing it wrong, means it is probably the least worst solution. I do a cascade of attempting to construct using SysTime.fromISOString, SysTime.fromISOExtString, DateTime.fromISOString, DateTime.fromISOExtString, Date.fromISOString, Date.fromISAExtString (creating a SysTime in the latter four cases obviously).

>     catch(DateTimeException)
>     {
>         // If it's just HH:MM:SS
>         st = SysTime(Date.init, TimeOfDay.fromISOExtString(str));
>     }
> }

I haven't got to this stage as yet, but I suspect I am going to have to.

> But that would be downright bizarre in the case where it was just
> HH:MM:SS,
> because then you'd end up with a SysTime on January 1st, 1 A.D. And
> while
> getting just the date is less awkward, it's still kind off to then
> operate
> on that as a SysTime. The time would always be at midnight.

I think you have to use the current date/time and extract the Date to initialise. Times have to be in extended format to avoid the YYYY HHMM conflict you pointed out.

> Really, just parsing an "ISO formatted string" and allowing either
> the date
> or time to be optional doesn't make much sense to me. That implies
> that you
> don't really know what it's for, since the meaning of something that
> is just
> a date and the meaning of something that is just a time are
> completely
> different.

I disagree. There is now and some temporal location in the past. Separating out durations makes that easy. Using a time means sometime today before now or is an error. Using a date/time means before today or is an error. This is not a general case, it is a specific need for the use of two date/times, and it seems all viable to me. Actually I can probably separate date/times and times as well as separating out durations before now to make things easier.

> Regardless, std.datetime was designed with the idea that you knew
> whether
> you were dealing with a date, a time, or both a date and a time when
> dealing
> with ISO formatted strings.

I'll get round it. Now I have "from the horses mouth" the guidance around my questions, I am fairly confident of where to go to achieve the goal. It will not be pretty, but it will be doable without having to create a magic parsing function.

Thanks for your exchanges on this, most constructive and most helpful.

-- 
Russel. ============================================================================= Dr Russel Winder      t: +44 20 7585 2200   voip: sip:russel.winder@ekiga.net 41 Buckmaster Road    m: +44 7770 465 077   xmpp: russel@winder.org.uk London SW11 1EN, UK   w: www.russel.org.uk  skype: russel_winder