【问题标题】:How do I convert Paypal's HH:MM:SS DD Mmm(.) YYYY PST/PDT to a C# UTC DateTime?如何将 Paypal 的 HH:MM:SS DD Mmm(.) YYYY PST/PDT 转换为 C# UTC DateTime?
【发布时间】:2011-09-23 22:00:24
【问题描述】:

我想在 SQL Server 数据库中以这种格式记录 payment_date。

更新。本能在这一点上是正确的。在这里找到了解决方案:http://www.codeillustrator.com/2010/03/converting-paypal-paymentdate-to-net.html,正在验证...当然,如果 Paypal 搬出西海岸,我会遇到麻烦。有没有更好的方法来解析这个?也许与 TimeZone?

public static DateTime ConvertPayPalDateTime(string payPalDateTime)
{
    // accept a few different date formats because of PST/PDT timezone and slight month difference in sandbox vs. prod.
    string[] dateFormats = { "HH:mm:ss MMM dd, yyyy PST", "HH:mm:ss MMM. dd, yyyy PST", "HH:mm:ss MMM dd, yyyy PDT", "HH:mm:ss MMM. dd, yyyy PDT" };
    DateTime outputDateTime;

    DateTime.TryParseExact(payPalDateTime, dateFormats, new CultureInfo("en-US"), DateTimeStyles.None, out outputDateTime);

    // convert to local timezone
    outputDateTime = outputDateTime.AddHours(3);

    return outputDateTime;
}

等一下,上面的代码对我来说是完全错误的。我在西海岸!理想情况下,这应该更新以将日期发送到适当的 UTC DateTime 并处理任何时区。上面的代码也不能正确处理 PDT(如果转换为 UTC)。

Update2. 显然,至少在以前的版本中,沙盒会返回“Feb.”。而现场返回“二月”。哈哈。谁来救救我!

Update3. 链接到正则表达式版本http://www.ifinity.com.au/Blog/EntryId/77/Converting-PayPal-Dates-to-Net-DateTime-using-Regex,但调试可能是个问题。正则表达式似乎不是正确的方法。一定有更好的办法。

/// <summary>
/// Converts a PayPal datestring into a valid .net datetime value
/// </summary>
/// <param name="dateValue">a string containing a PayPal date</param>
/// <param name="localUtcOffset">the number of hours from UTC/GMT the local 
/// time is (ie, the timezone where the computer is)</param>
/// <returns>Valid DateTime value if successful, DateTime.MinDate if not</returns>
private static DateTime ConvertFromPayPalDate(string rawPayPalDate, int localUtcOffset)
{
    /* regex pattern splits paypal date into
     * time : hh:mm:ss
     * date : Mmm dd yyyy
     * timezone : PST/PDT
     */
     const string payPalDateRegex = @"(?<time>\d{1,2}:\d{2}:\d{2})\s(?<date>(?<
Mmm>[A-Za-z\.]{3,5})\s(?<dd>\d{1,2}),?\s(?<yyyy>\d{4}))\s(?<tz>[A-Z]{0,3})";  
    //!important : above line broken over two lines for formatting - rejoin in code editor
    //example 05:49:56 Oct. 18, 2009 PDT
    //        20:48:22 Dec 25, 2009 PST
    Match dateMatch = Regex.Match(rawPayPalDate, payPalDateRegex, RegexOptions.IgnoreCase);
    DateTime time, date = DateTime.MinValue;
    //check to see if the regex pattern matched the supplied string
    if (dateMatch.Success)
    {
        //extract the relevant parts of the date from regex match groups
        string rawDate = dateMatch.Groups["date"].Value;
        string rawTime = dateMatch.Groups["time"].Value;
        string tz = dateMatch.Groups["tz"].Value;

        //create date and time values
        if (DateTime.TryParse(rawTime, out time) && DateTime.TryParse(rawDate, out date))
        {
            //add the time to the date value to get the datetime value
            date = date.Add(new TimeSpan(time.Hour, time.Minute, time.Second));
            //adjust for the pdt timezone.  Pass 0 to localUtcOffset to get UTC/GMT
            int offset = localUtcOffset + 7; //pdt = utc-7, pst = utc-8
            if (tz == "PDT")//pacific daylight time
                date = date.AddHours(offset);
            else  //pacific standard time
                date = date.AddHours(offset + 1);
        }
    }
    return date;
}

【问题讨论】:

  • 你想用哪种格式登录db?到目前为止,您尝试过什么?
  • 付费 DATETIME,还没有尝试过任何东西 - 虽然这可能会解决问题codeillustrator.com/2010/03/…
  • 请注意,链接代码不区分 PST 和 PDT,因此每年都会中断一个小时!
  • @tc,我们如何做到这一点?我可以在 .NET 中使用时区功能吗?
  • 我的服务器在亚洲,用UTC跟踪时间,可能会中断半年!

标签: c# date


【解决方案1】:

自 2006 年以来我没有做过任何 C#,所以这段代码可能无法编译。飞行前进行测试!

public static DateTime ConvertPayPalDateTime(string payPalDateTime)
{
  // Get the offset.
  // If C# supports switching on strings, it's probably more sensible to do that.
  int offset;
  if (payPalDateTime.EndsWith(" PDT"))
  {
     offset = 7;
  }
  else if (payPalDateTime.EndsWith(" PST"))
  {
     offset = 8;
  }
  else
  {
    throw some exception;
  }

  // We've "parsed" the time zone, so remove it from the string.
  payPalDatetime = payPalDateTime.Substring(0,payPalDateTime.Length-4);

  // Same formats as above, but with PST/PDT removed.
  string[] dateFormats = { "HH:mm:ss MMM dd, yyyy", "HH:mm:ss MMM. dd, yyyy" };

  // Parse the date. Throw an exception if it fails.
  DateTime ret = DateTime.ParseExact(payPalDateTime, dateFormats, new CultureInfo("en-US"), DateTimeStyles.None, out outputDateTime);

  // Add the offset, and make it a universal time.
  return ret.AddHours(offset).SpecifyKind(DateTimeKind.Universal);
}

【讨论】:

    【解决方案2】:

    这应该可以工作

     public static DateTime ConvertPayPalDateTime(string payPalDateTime)
     { 
        CultureInfo enUS = new CultureInfo("en-US");
        // accept a few different date formats because of PST/PDT timezone and slight month difference in sandbox vs. prod.
        string[] dateFormats = { "HH:mm:ss MMM dd, yyyy PST", "HH:mm:ss MMM. dd, yyyy PST", "HH:mm:ss MMM dd, yyyy PDT", "HH:mm:ss MMM. dd, yyyy PDT",
                                 "HH:mm:ss dd MMM yyyy PST", "HH:mm:ss dd MMM. yyyy PST", "HH:mm:ss dd MMM yyyy PDT", "HH:mm:ss dd MMM. yyyy PDT"};
        DateTime outputDateTime;
    
        DateTime.TryParseExact(payPalDateTime, dateFormats, CultureInfo.InvariantCulture, DateTimeStyles.None, out outputDateTime);
    
        // convert to local timezone
        TimeZoneInfo hwZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
    
        outputDateTime = TimeZoneInfo.ConvertTime(outputDateTime, hwZone, TimeZoneInfo.Local);
    
        return outputDateTime;
    }
    

    【讨论】:

      【解决方案3】:

      这篇文章中的代码似乎可以正常工作:http://www.codeillustrator.com/2010/03/converting-paypal-paymentdate-to-net.html

      using System;
      using System.Globalization;
      
      public static class PayPalTransaction
      {
          public static DateTime ConvertPayPalDateTime(string payPalDateTime)
          {
          // accept a few different date formats because of PST/PDT timezone and slight month difference in sandbox vs. prod.
              string[] dateFormats = { "HH:mm:ss MMM dd, yyyy PST", "HH:mm:ss MMM. dd, yyyy PST", "HH:mm:ss MMM dd, yyyy PDT", "HH:mm:ss MMM. dd, yyyy PDT" };
              DateTime outputDateTime;
      
              DateTime.TryParseExact(payPalDateTime, dateFormats, new CultureInfo("en-US"), DateTimeStyles.None, out outputDateTime);
      
              // convert to local timezone
              outputDateTime = outputDateTime.AddHours(3);
      
              return outputDateTime;
          }
      }
      

      (针对类似问题交叉发布的答案:How to cast this date and save to database

      【讨论】:

        【解决方案4】:

        假设您已经使用DateTime.ParseExact()(或其他类似方法之一)解析了日期,您可以调用DateTime.ToUniversalTime()

        编辑:也许 TimeZoneInfo.ConvertTimeToUtc 更合适: ToUniversalTime 方法将 DateTime 值从本地时间转换为 UTC。要将非本地时区的时间转换为 UTC,请使用 TimeZoneInfo.ConvertTimeToUtc(DateTime, TimeZoneInfo) 方法。要转换与 UTC 的偏移量已知的时间,请使用 ToUniversalTime 方法。

        【讨论】:

        • 我不确定我是否可以信任我的 ParseExact。
        • -1。 ToUniversalTime() 会将其解释为您当地时区的时间,这会增加更多需要处理的边缘情况(我认为 Windows 也不保留历史时区数据)。
        猜你喜欢
        • 1970-01-01
        • 2010-10-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多