将UTC时间转换为PST以获得夏令时?

Posted

技术标签:

【中文标题】将UTC时间转换为PST以获得夏令时?【英文标题】:Convert UTC time to PST for Daylight savings time? 【发布时间】:2016-06-14 08:07:46 【问题描述】:

我的应用程序从后端获取一些时隙并将其转换为当前时区 (PST) 并显示。在开始节省日光时间之前,一切都运行良好。

ios 中有没有办法说像给我这个 UTC 的 PST 日期和时间,它会自动处理夏令时。目前它的转换很好,但仍然给我一个小时的休息时间。

这就是我正在做的事情:

-(NSDate *) toLocalTime:(NSDate*) currentDate

    NSTimeZone *tz = [NSTimeZone timeZoneWithName:@"US/Pacific"];
    NSInteger seconds = [tz secondsFromGMTForDate: currentDate];
    return [NSDate dateWithTimeInterval: seconds sinceDate: currentDate];

编辑

把我的代码改成这个,结果还是一样:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
    dateFormatter.dateFormat = @"MM/dd/yyyy HH:mm:ss";
    [dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];

    NSString *startDateString = [[self.slotsArray objectAtIndex:indexPath.row] objectForKey:@"StartDate"];
    NSDate *startDate = [dateFormatter dateFromString:startDateString];

    dateFormatter.dateStyle = NSDateFormatterMediumStyle;
    dateFormatter.timeStyle = NSDateFormatterMediumStyle;
    [dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"America/Los_Angeles"]];

    NSString * dateString = [dateFormatter stringFromDate:startDate];

例如,当白天开始时,我会显示 3 月 13 日的一些时间段。在 UTC 中,我得到的时间是 17:00,相当于我们今天的 10 点。但在这种情况下,实际时间是当天上午 9 点。我该如何解决?

【问题讨论】:

基本上使用NSCalendarNSDateComponents 进行所有 日历计算,而不是使用像86400 这样的文字数字 “在这种情况下,实际时间是当天上午 9 点”是什么意思?如果您不想进行简单的时区转换(产生上午 10 点),请描述您希望如何转换时间。 【参考方案1】:

我不知道该方法应该做什么,但NSDate 没有任何时区信息,所以如果您将一个时区从一个时区“调整”到另一个时区,那么您就是在这样做错误的。 NSDate 的文档甚至说

NSDate 对象封装单个时间点,独立于任何特定的日历系统或时区。

如果您有一个NSDate,并且希望在给定时区的当地时间将其呈现给用户,您可以执行以下操作:

NSDate *date = // from somewhere

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateStyle = NSDateFormatterMediumStyle;
formatter.timeStyle = NSDateFormatterMediumStyle;
formatter.timeZone = [NSTimeZone timeZoneWithName:@"America/Los_Angeles"];

NSString *dateString = [formatter stringFromDate:date];

这将为您提供一个字符串,其中包含给定时区的正确日期,对于您向其抛出的任何NSDate。不要尝试转换NSDate

额外基于评论:

2016 年美国的夏令时从 3 月 13 日 02:00 开始。此时时间将向前一小时。如果您使用开始日期字符串@"03/12/2016 17:00:00"(在时间更改之前)运行上述代码,则最终结果为Mar 12, 2016, 9:00:00 AM。如果使用开始日期字符串@"03/13/2016 17:00:00"(时间更改后)运行它,则结果为Mar 13, 2016, 10:00:00 AM

因此,代码通过在 DST 开始之前和之后返回不同的时间以及通过在 DST 期间正确返回一天中的较晚时间来正确调整夏令时。您似乎得到了相同的结果,所以我不再确定您要解决什么问题。

【讨论】:

见我上面的编辑。我认为通过这两种方式中的任何一种,我都可以获得今天的正确日期。但是今天上午 10 点将是当天上午 9 点。但如果我今天看它,它显示的是 10 而不是 9。我得到的 UTC 是 17:00:00 您能否举例说明您开始使用的日期字符串会导致不正确的结果? 这是我在 startDateString "03/13/2016 17:00:00" 中获得的值,然后我的 dateString 出现为 "Mar 13, 2016, 10:00:00 AM" 这是正确,但那天应该是上午 9:00。 没有。北美太平洋时区的夏令时从 2016-03-13 10:00:00 UTC 开始,在 2016-03-13 17:00:00 UTC 之前。因此,2016 年 3 月 13 日 17:00:00 UTC 的太平洋时区偏移量为 -7 小时。 17 - 7 = 10,因此 2016-03-13 17:00:00 UTC 在太平洋时区是 2016-03-13 10:00:00。【参考方案2】:

不要使用US/Pacific,而是尝试将其替换为America/Los_Angeles,它会自动检测DST并将时区更改为-7

我在一些应用程序上工作,从服务器获取 UTC 时间,我们在使用它时从来没有遇到过问题。

【讨论】:

【参考方案3】:

斯威夫特 4: 给定日期格式 "2018-03-13 07:00:00 +0000" 返回值应为 ""2018-03-12"

func PDTForamte(endTime: String) -> String
    // create dateFormatter with UTC time format
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss+zzzz"
    dateFormatter.timeZone = TimeZone(identifier: "UTC")

    guard let date = dateFormatter.date(from: endTime) else 
        return endTime.components(separatedBy: "T").first ?? "" //return date before 'T'.
    

    let pdtFormatter = DateFormatter()
    pdtFormatter.dateStyle = .long
    pdtFormatter.timeStyle = .long
    if let americaZone = NSTimeZone(name: "America/Los_Angeles") 
        pdtFormatter.timeZone = americaZone as TimeZone
    

    let dateString: String = pdtFormatter.string(from: date)

    let calendar = NSCalendar.autoupdatingCurrent
    //We subtract 1 min because American Date here be 12:00:00 AM but It should be return to the previous day
    let newDate = calendar.date(byAdding: .minute, value: -1, to: pdtFormatter.date(from: dateString)!) ?? Date()
    pdtFormatter.dateFormat = "yyyy-MM-dd"
    let newDateString: String = pdtFormatter.string(from: newDate)

    return newDateString

【讨论】:

以上是关于将UTC时间转换为PST以获得夏令时?的主要内容,如果未能解决你的问题,请参考以下文章

将 PST 中的日期与时间转换为 UTC 格式

将某人的当地时间转换为 UTC 时间

查询 Django 模型时,如何将 Django 中的 DateTimeField 从 UTC 转换为最终用户的时区(通常是 PST)?

WordPress 从哪里获得夏令时信息

将 UTC 转换为 EST 不适用于 Android 上的夏令时

TSQL:如何将本地时间转换为 UTC? (SQL Server 2008)