0

I'm having issues parsing a time span, i have a start and end time for a dataset and the step is formatted like this 0000-00-00.01:00:00 so in this case it's only an hour between. but it might be days etc so it has to keep some support.

The issue is that a line like this

const string TimeSpanFormat = @"yyyy-MM-dd\.hh\:mm\:ss";
TimeSpan.ParseExact(StepToConvert, TimeSpanFormat, CultureInfo.InvariantCulture)

or like this

DateTime.ParseExact(StepToConvert, TimeSpanFormat, CultureInfo.InvariantCulture).TimeOfDay

returns both the error

Additional information: The DateTime represented by the string is not supported in calendar System.Globalization.GregorianCalendar.

so I'm kind of at a loss, with the exception of making a helper class/structure. works fine on times like 2013-01-01.00:00:00 for Datetime btw.

Any bright ideas in the community on this?

Thomas Andreè Wang
  • 3,379
  • 6
  • 37
  • 53

2 Answers2

4

For TimeSpan.ParseExact, there is no custom timespan format strings for yyyy and MM. These are some problematic subjects for a TimeSpan. It is just a time interval. Duration of a month or year depends on a lot of stuff.

For DateTime.ParseExact, first of all, your 0000-00-00.01:00:00 is less than DateTime.MinValue. You can't parse a string that doesn't exist as a DateTime. Even if your string is available DateTime value, your string and your format doesn't match at all. For a string like 2013-01-01.00:00:00, your TimeSpanFormat should be yyyy-MM-dd.HH:mm:ss and preferable an IFormatProvider has : as a TimeSeparator.

string s = "2013-01-01.00:00:00";
const string format = "yyyy-MM-dd.HH:mm:ss";
DateTime.ParseExact(s, format, CultureInfo.InvariantCulture).TimeOfDay // 00:00:00
Community
  • 1
  • 1
Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
  • 2
    @Downvoter care to comment at least so I can see where I _might_ be wrong? – Soner Gönül Jun 23 '15 at 08:14
  • 1
    I haven't downvoted but the core issue of this question seems to be how to parse a `DateTime` `0000-00-00.01:00:00` successfully since OP cant change the fact that it exists and must be interpreted as zero timespan. The only approach that comes to my mind is to check if it's `0000-00-00` and change it to `0001-01-01`. – Tim Schmelter Jun 23 '15 at 09:06
  • @TimSchmelter That might be. Changing `0000-00-00` to `0001-01-01` process is provided by OP in his own answer, so I wouldn't dare to change mine :) – Soner Gönül Jun 23 '15 at 09:14
0

This has nothing to do with dates, so you can use the "bank" method and count months and years for 30 days and 360 days - or what fits best (if at all needed).

Then do a custom split and calculation and add the pieces:

string step = "0001-02-03.01:00:00";

string[] parts = step.Split(new string[] {"-", "."}, StringSplitOptions.None);

TimeSpan hours = TimeSpan.Parse(parts[3]);
TimeSpan days = new TimeSpan(int.Parse(parts[2]), 0, 0, 0);
TimeSpan months = new TimeSpan(int.Parse(parts[1]) * 30, 0, 0, 0);
TimeSpan years = new TimeSpan(int.Parse(parts[0]) * 360, 0, 0, 0);
TimeSpan total = hours.Add(days).Add(months).Add(years);

Console.WriteLine(total.ToString());

Result from the example is 423.04:00:00.

Gustav
  • 53,498
  • 7
  • 29
  • 55