0

I have a scenario where I need to parse strings representing datetimes.

The length of the string implies the precision:

  • "2012-11-11" represents any moment in "november 11 of 2012"
  • "2012-11" represents any moment in "november of 2012"
  • "2012-11-11 10:11" represents any seconds in that minute

I would need to parse these strings as ranges of time.

Is there a datastructure that can help representing this or do I need to parse it manually and use 2 DateTimes.

vinczemarton
  • 7,756
  • 6
  • 54
  • 86
  • 1
    Which one is month? First `11` or second one? Your one-digit numbers has leading zeros? `2012-01-01` or `2012-1-1`? What do you mean as a _ranges of time_? Do you mean any time on `November 2012` in your second example? And any second on `2012-11-11 10:11` minute? `DateTime.TryParseExact` has an overload that takes string array as a format but since you looking for a range, you need to check their properties manually. For example; for your first example, you need to check it's `Year`, `Month` and `Day` properties. – Soner Gönül May 06 '15 at 14:11
  • I would suggest just manually parsing the strings. – Ellis May 06 '15 at 14:13
  • 1
    I'm not entirely clear why you can't just use `DateTime.Parse()` or perhaps `DateTime.ParseExact()`.... Is it that you're looking to get a `TimeSpan` object instead of a `DateTime`? – Dan Field May 06 '15 at 14:13
  • How bad can it get? Do you need to accept `2012-11-1` as "any moment that occurred on or after 10th November 2012 and before 20th November 2012"? Or will components always be either present or absent? (And the previous suggested input is either not allowed or just represents the 1st) – Damien_The_Unbeliever May 06 '15 at 14:14
  • 1
    data as meta data is typically a bad idea...which makes it all the more fun to code. You really should set a second field with the precision as an enum (Precison.Day, Precision.Minute, etc) and the the DateTime as a DateTime. – Mike_Matthews_II May 06 '15 at 14:15
  • there is TimeSpan structure, however it will require other string format containing both bounds to parse https://msdn.microsoft.com/en-us/library/se73z7b9(v=vs.110).aspx – Victor May 06 '15 at 14:15
  • 1
    It may be useful, look here: http://stackoverflow.com/questions/1845493/should-i-make-a-daterange-object – Sasha Truf May 06 '15 at 14:19
  • NodaTime http://nodatime.org seems to provide the data structures you need, though I guess you still have to parse your self. – Greg May 06 '15 at 14:39

2 Answers2

1

You will have to write your own class to manage this.

Let's assume that your date strings are always in one of the following formats:

  • yyyy-M-d HH:mm:ss
  • yyyy-M-d HH:mm
  • yyyy-M-d HH
  • yyyy-M-d
  • yyyy-M
  • yyyy

Then you can write a class to encapsulate this as follows:

public sealed class TimeRange
{
    public TimeRange(string dateTimeString)
    {
        DateTime dateTime;

        if (DateTime.TryParseExact(dateTimeString, @"yyyy-M-d HH\:mm\:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
        {
            _start = dateTime;
            _end   = dateTime.AddSeconds(1);
        }
        else if (DateTime.TryParseExact(dateTimeString, @"yyyy-M-d HH\:mm", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
        {
            _start = dateTime;
            _end   = dateTime.AddMinutes(1);
        }
        else if (DateTime.TryParseExact(dateTimeString, @"yyyy-M-d HH", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
        {
            _start = dateTime;
            _end   = dateTime.AddHours(1);
        }
        else if (DateTime.TryParseExact(dateTimeString, @"yyyy-M-d", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
        {
            _start = dateTime;
            _end   = dateTime.AddDays(1);
        }
        else if (DateTime.TryParseExact(dateTimeString, @"yyyy-M", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
        {
            _start = dateTime;
            _end =   dateTime.AddMonths(1);
        }
        else if (DateTime.TryParseExact(dateTimeString, @"yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
        {
            _start = dateTime;
            _end   = dateTime.AddYears(1);
        }
        else
        {
            throw new ArgumentException("date/time is invalid: " + dateTimeString, "dateTimeString");
        }
    }

    public DateTime Start
    {
        get
        {
            return _start;
        }
    }

    public DateTime ExclusiveEnd
    {
        get
        {
            return _end;
        }
    }

    private readonly DateTime _start;
    private readonly DateTime _end;
}

Note that for simplicity the end of the range, ExclusiveEnd, is expressed as an exclusive range. That means you'd make comparisons like:

if (timeRange.Start <= targetDateTime && targetDateTime < timeRange.ExclusiveEnd)
    ...

rather than the following, which would be incorrect:

if (timeRange.Start <= targetDateTime && targetDateTime <= timeRange.ExclusiveEnd)
    ...

Note the difference between < timeRange.ExclusiveEnd and <= timeRange.ExclusiveEnd

To avoid this subtlety you could add to the class a Contains(DateTime) method like:

public bool Contains(DateTime target)
{
    return (_start <= target) && (target < _end);
}
Matthew Watson
  • 104,400
  • 10
  • 158
  • 276
0

A DateTime doesn't represent a period of time, it represents a specific moment in time.

You could use DateTime.TryParse() to parse the string however the interpretation of that is up to you.

https://msdn.microsoft.com/en-us/library/system.datetime.tryparse%28v=vs.110%29.aspx

Example

        string foo = "11 August 2016";
        DateTime bar = DateTime.Now;

        DateTime.TryParse(foo, out bar);
        Console.WriteLine(bar.ToString());

will output 11/08/2016 00:00:00

so you could assume this represents any time from 11/08/2016 to 11/08/2016 23:59:59 although it will miss out the case where the time specified was specifically 11/08/2016 00:00:00. Is this a likely input??

Could you gave a bit more info on why you need to interpret it this way?

Notts90
  • 254
  • 2
  • 20
  • [Are answers that just contain links elsewhere really “good answers”?](http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really-good-answers) – Soner Gönül May 06 '15 at 14:18
  • It was a point in the right direction, added an example on how to use it – Notts90 May 06 '15 at 14:24
  • The question is about much more than just parsing a date time. It involves different formats which result in different meanings and requires a start and end or start and duration as the result. – juharr May 06 '15 at 14:34