以多种格式parsingdate时间

我已经创build了一个API端点。 调用者可以通过POST方法调用API来传递相关参数。 在参数中有一个是datetime格式的参数。

问题是当调用这个API时,调用者可能以三种不同的格式传递datetime

  1. long int – 例如1374755180
  2. 美国格式 – 例如“7/25/2013 6:37:31 PM”(作为string
  3. 时间戳格式 – 例如“2013-07-25 14:26:00”(以string

我必须parsingdatetime值并将其转换为时间戳格式的DateTimestring

我曾尝试使用DateTime.TryParse()DateTime.Parse()Convert.ToDateTime()Convert.ToDouble()但他们都没有确定的工作对我来说。

所需的输出必须采用en-GB格式。

编辑:

我曾经想过有一个if-else if-else块与TryParse一起使用3次, else说这个string不能被parsing。 这是最好的解决scheme吗? 还是有解决scheme比这更好?

请帮忙!

你应该考虑需要一个时区。 1不需要它,但#2和#3做。

 public DateTime ParseRequestDate() { // https://stackoverflow.com/questions/2883576/how-do-you-convert-epoch-time-in-c CultureInfo enUS = new CultureInfo("en-US"); var dt = "1374755180"; //var dt = "7/25/2013 6:37:31 PM"; //var dt = "2013-07-25 14:26:00"; DateTime dateValue; long dtLong; // Scenario #1 if (long.TryParse(dt, out dtLong)) return dtLong.FromUnixTime(); // Scenario #2 if (DateTime.TryParseExact(dt, "MM/dd/yyyy hh:mm:ss tt", enUS, DateTimeStyles.None, out dateValue)) return dateValue; // Scenario #3 if (DateTime.TryParseExact(dt, "yyyy-MM-dd hh:mm:ss", enUS, DateTimeStyles.None, out dateValue)) return dateValue; throw new SomeException("Don't know how to parse..."); } 

编辑正如马特约翰逊指出,DateTime.TryParseExact接受格式string的数组。 2&3可以被浓缩。

 public DateTime ParseRequestDate() { // https://stackoverflow.com/questions/2883576/how-do-you-convert-epoch-time-in-c CultureInfo enUS = new CultureInfo("en-US"); var dt = "1374755180"; //var dt = "7/25/2013 6:37:31 PM"; //var dt = "2013-07-25 14:26:00"; DateTime dateValue; long dtLong; // Scenario #1 if (long.TryParse(dt, out dtLong)) return dtLong.FromUnixTime(); // Scenario #2 & #3 var formatStrings = new string[] { "MM/dd/yyyy hh:mm:ss tt", "yyyy-MM-dd hh:mm:ss" }; if (DateTime.TryParseExact(dt, formatStrings, enUS, DateTimeStyles.None, out dateValue)) return dateValue; throw new SomeException("Don't know how to parse..."); } 

我从另一个问题借用的时代转换。 (扩展方法)

 public static class MyExtensions { public static DateTime FromUnixTime(this long unixTime) { var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); return epoch.AddSeconds(unixTime); } } 

您正在寻找DateTime.ParseExact ( MSDN文章 )

你会用在这样的情况下:

 string[] formats= { "MM/dd/yyyy hh:mm:ss tt", "yyyy-MM-dd hh:mm:ss" } var dateTime = DateTime.ParseExact("7/25/2013 6:37:31 PM", formats, new CultureInfo("en-GB"), DateTimeStyles.None); 

这允许您根据需要添加尽可能多的DateTime格式,并且该方法将在没有ifelse语句的情况下执行转换。

如果你的整数是从Unix Epoch开始的秒数,那么你需要在Epoch的DateTime中加上秒数(01/01/1970)(.Net对此没有开箱即用的方法,但是逻辑是秒'时代'):

 new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(seconds); 

从这个问题 。

处理这个问题的一种方法是build立一个“理解”不同格式的工厂方法,并相应地parsing它们。

你可以创build一个ifthenelse的链来处理这个问题,但是你也可以创build一个“表驱动”的实现:你需要的是一个带有string的委托数组,告诉你两件事情:

  • 这个委托是否可以parsing传入的string,
  • 如果是的话,parsing的结果是什么,表示为DateTime

这是一个示例实现:

 private static readonly DateParsers = new Func<string,Tuple<DateTime,bool>>[] { (s) => { long res; if (long.TryParse(s, out res)) { // The format was correct - make a DateTime, // and return true to indicate a successful parse return Tuple.Create(new DateTime(res), true); } else { // It does not matter what you put in the Item1 // when Item2 of the tuple is set to false return Tuple.Create(DateTime.MinValue, false); } } ... // Add similar delegates for other formats here }; 

现在你的工厂方法可以实现如下:

 private static bool TryParseMultiformat(string s, out DateTime res) { // Check all parsers in turn, looking for one returning success foreach (var p in DateParsers) { var tmp = p(s); if (tmp.Item2) { res = tmp.Item1; return true; } } res = DateTime.MinValue; return false; } 

如果可能的格式是固定的,那么你可以使用TryParseExact

一个可能的解决scheme是使用TryParse ,如果它没有得到正确的date,然后回退到已知的格式,并使用TryPraseExact

感谢您的回答。 我尝试了几个答案中提出的选项,并find了一个非常简单的方法,为我工作。

 public static bool ParseDate(string dateString, out DateTime dateValue) { long dtLong = 0L; bool result = false; if (long.TryParse(dateString, out dtLong)) { // I copied the epoch code here for simplicity dateValue = new DateTime(1970, 1, 1, 0, 0, 0).AddSeconds(dtLong); result = true; } // Working for US and Timestamp formats else if (DateTime.TryParse(dateString, out dateValue)) result = true; return result; } 

早些时候,我试图使用TryParse的所有3种格式不工作。

不知何故, TryParseExact不适用于时间戳格式。 它适用于美国的格式。 这就是我必须自己写的原因。

如果您使用TryParseExact ,只有GOD和Microsoft开发人员知道在放弃之前会尝试parsing多less个可能的date时间格式。 也许更好的解决scheme是使用快速正则expression式,然后使用适当的parsing器。 我试图使正则expression式尽可能简单,你可能不得不调整这一点

  private static readonly Regex R1 = new Regex(@"^\d+$", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline); private static readonly Regex R2 = new Regex(@"M$", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline); private static readonly Regex R3 = new Regex(@"^\d{4}-", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline); private static void Main(string[] args) { string[] stringDates = new[] { "1374755180", "2013-07-25 14:26:00", "7/25/2013 6:37:31 PM" }; foreach (var s in stringDates) { DateTime date = default(DateTime); if (R1.IsMatch(s)) date = new DateTime(long.Parse(s)); else if (R2.IsMatch(s)) date = DateTime.Parse(s); else if (R3.IsMatch(s)) date = DateTime.Parse(s); if (date != default(DateTime)) Console.WriteLine("{0}", date); } Console.WriteLine("Press ENTER to continue..."); Console.ReadLine(); } 

我在一个项目中遇到了同样的问题,在这个项目中,我的代码可以在不同的文化格式的环境中运行

Google向我展示了这个隐藏的gem 。 无论文化格式如何,助手function对于自动parsingdate时间都是必不可less的

用法示例:

 string str = @"The last round was June 10, 2005; this time the unbroken record was held."; DateTimeRoutines.ParsedDateTime pdt; if (DateTimeRoutines.TryParseDate(str, DateTimeRoutines.DateTimeFormat.USA_DATE, out pdt)) Console.WriteLine("Date was found: " + pdt.DateTime.ToString()); 

根据作者,代码是能够parsing各种情况:

 @"Member since: 10-Feb-2008" @"Last Update: 18:16 11 Feb '08 " @"date Tue, Feb 10, 2008 at 11:06 AM" @"see at 12/31/2007 14:16:32" @"sack finish 14:16:32 November 15 2008, 1-144 app" @"Genesis Message - Wed 04 Feb 08 - 19:40" @"The day 07/31/07 14:16:32 is " @"Shipping is on us until December 24, 2008 within the US" @" 2008 within the US at 14:16:32" @"5th November, 1994, 8:15:30 pm" @"7 boxes January 31 , 14:16:32." @"the blue sky of Sept 30th 2008 14:16:32" @" eg 1997-07-16T19:20:30+01:00" @"Apr 1st, 2008 14:16:32 tufa 6767" @"wait for 07/31/07 14:16:32" @"later 12.31.08 and before 1.01.09" @"Expires: Sept 30th 2008 14:16:32" @"Offer expires Apr 1st, 2007, 14:16:32" @"Expires 14:16:32 January 31." @"Expires 14:16:32 January 31-st." @"Expires 23rd January 2010." @"Expires January 22nd, 2010." @"Expires DEC 22, 2010."