4

Has anyone ever heard of, or have access to some c# string extension snippet(s) or library that turns stuff like "yesterday", "today", "tomorrow" into DateTimes or "8 seconds ago", "10 minutes from now" into TimeSpans?

If not, any thoughts on what that might look like in C#?

Thanks

coach_rob
  • 877
  • 13
  • 28
  • You could write something yourself to do what you are asking... instead of relying on extensions ;) – craig1231 Apr 05 '13 at 22:13
  • Are we talking about understanding strings written in natural language, or "DateTime.Yesterday", "DateTime.Tomorrow" functions? – Haedrian Apr 05 '13 at 22:25
  • If you want to turn a string `"yesterday"` into a DateTime, then there isn't an extension for that. If there were, it'd have to support all kinds of languages and not just English. – Nolonar Apr 05 '13 at 22:29
  • Side note: if you are really into such interesting time values it may be good idea to have custom type - i.e. "yesterday" is actually a range, while "8 seconds ago" is pair of {offset, current time} where "current time" may be value or function... – Alexei Levenkov Apr 06 '13 at 00:56

3 Answers3

9

I got this from somewhere, at some point.

public static string ElapsedTime(DateTime dtEvent) 
{ 
    TimeSpan TS = DateTime.Now - dtEvent; 
    int intYears = DateTime.Now.Year - dtEvent.Year; 
    int intMonths = DateTime.Now.Month - dtEvent.Month; 
    int intDays = DateTime.Now.Day - dtEvent.Day; 
    int intHours = DateTime.Now.Hour - dtEvent.Hour; 
    int intMinutes = DateTime.Now.Minute - dtEvent.Minute; 
    int intSeconds = DateTime.Now.Second - dtEvent.Second; 
    if (intYears > 0) return String.Format("{0} {1} ago", intYears, (intYears == 1) ? "year" : "years");
    else if (intMonths > 0) return String.Format("{0} {1} ago", intMonths, (intMonths == 1) ? "month" : "months");
    else if (intDays > 0) return String.Format("{0} {1} ago", intDays, (intDays == 1) ? "day" : "days");
    else if (intHours > 0) return String.Format("{0} {1} ago", intHours, (intHours == 1) ? "hour" : "hours");
    else if (intMinutes > 0) return String.Format("{0} {1} ago", intMinutes, (intMinutes == 1) ? "minute" : "minutes");
    else if (intSeconds > 0) return String.Format("{0} {1} ago", intSeconds, (intSeconds == 1) ? "second" : "seconds"); 
    else 
    { 
        return String.Format("{0} {1} ago", dtEvent.ToShortDateString(), dtEvent.ToShortTimeString()); 
    } 
} 
Cortright
  • 1,164
  • 6
  • 19
5

I dont know of any libraries that do this out of the box, but its easy enough to just write your own:

public static class DateTimeExtensions
{

public static DateTime Yesterday (this DateTime x)
{
return x.AddDays(-1);
}

}

you can then do something like:

var yesterday = DateTime.Now.Yesterday();

Edit: it seems like you just want to convert verbatim strings into datetimes. I dont see how you could do this without explicitly mapping certain strings to a certain condition, e.g.

public static DateTime GiveMeADateTime(this string stringValue)
{
switch (stringValue)
{
case "today": return DateTime.Now;
case "tomorrow": return DateTime.Now.AddDays(1);
default: return DateTime.Now;
}
}

You could then use it like:

var todaysDate = "today".GiveMeADateTime();

Do note that this isnt very dynamic nor is it maintainable. But I guess that should maybe give you some ideas.

Thousand
  • 6,562
  • 3
  • 38
  • 46
2

And since this is getting to be an open debate on the subject...

I haven't seen anything similar, for C# or otherwise, so:

You need a parser, obviously...

1) make a 'handy' parser yourself - depending on the 'language' you're targeting here, if it's simplistic enough you could get away with simple 'tokenizing', just filtering 'known words' (e.g. don't mind the lexical analysis etc., allow for 'strange' words), put them in the basket and extracting numbers. Match seconds, etc., number of, and some phrases. It's not ideal, far from it but if simple, it's good if it works.

2) RegEx is not ideal for AST types of problems - but again, if you minimize the problem you could parse out some of it. Personally, I wouldn't, but if you need a quick and dirty and don't have a real language, just parsing out simple formats, try it out

3) For a more complex - and better solutions - go with a first-grade parser like Antlr which has libs for C# (though very little help - but if needed, put a more concrete question up and I'll try to dig some code).
There is also the Irony which is an expressions based C# native parser - and lot of fun to work with (though not as fast or performant as Antlr it may not matter to you, easier to work with, more help etc.). See also

NSGaga-mostly-inactive
  • 14,052
  • 3
  • 41
  • 51