重要的:
首先,我做了:
NSInteger tzOffset = [[NSTimeZone systemTimeZone] secondsFromGMT];
NSDate *localDate = [inputDate dateByAddingTimeInterval:tzOffset];
int daylightOffset = [[NSTimeZone localTimeZone] daylightSavingTimeOffset];
BOOL isDaylightSavingTimeForDate =
[[NSTimeZone localTimeZone] isDaylightSavingTimeForDate:inputDate];
if (!isDaylightSavingTimeForDate) {
localDate = [localDate dateByAddingTimeInterval:-1*daylightOffset];
}
time_t localTime = (time_t) [localDate timeIntervalSince1970];
仅当DaylightOffset
对系统有效时才有效。
[[NSTimeZone localTimeZone] daylightSavingTimeOffset]
返回0
; isDaylightSavingTimeForDate:inputDate
返回true
是否有更好的方法将NSDate转换为time_t,其值代表本地TZ
示例:
我住在太平洋标准时间。 2017年11月UTC = -8小时,2018年5月,UTC = -7小时
我想要的是localDate = 2018-05-04 13:00:00 UTC
答案 0 :(得分:3)
我需要将NSDate转换为time_t
time_t time = (time_t)[date timeIntervalSince1970];
这就是答案。
NSDate包含UTC时间
NSDate从不包含任何类型的时区。 NSDate是自参考时间以来的绝对秒数。你所在的时区并不重要。如果你在地球上并不重要。您正在使用的日历,时钟或其他人类设备无关紧要。这是一个绝对的时间点,每个人都会同意(忽略相对论效应)。
time_t必须包含本地时区的值
time_t与NSDate相同。它永远没有时区。这是一个时代以来的几秒钟。如果您认为它有时区,或者希望它有时区,那么您使用的是错误的工具。
2017年11月,我想显示 2018年5月4日下午1:00。
(强调我的)如果你想要展示某些东西,你需要一个NSDateFormatter
。您不希望更改特定事件与纪元的秒数,您只想以时区感知的方式对其进行描述。
如果您想在基于日历的日期进行计算,那么您需要NSDateComponents
。它增加了诸如“小时”和“天”这样的东西。使用NSDate的唯一时间单位是第二个。
- 输入日期= 2018-05-04 20:00:00 UTC
- localDate = 2018-05-04 13:00:00 UTC
这没有意义。为什么要在“输入日期”之前7小时发生“localDate”?你说你想要以不同的方式展示东西,但这表明它们发生在不同的时间点。如果目标是以不同方式显示,那么NSDateFormatter
将会这样做。只需设置时区。
如果目标是在事件发生时实际更改,则可以使用dateByAddingTimeInterval:
添加或减去要调整的时间。但这与时区无关;它将它移动到宇宙历史中的另一个点。
在这种情况下你在使用time_t
是什么?
在太平洋标准时间显示2018-05-04 20:00:00 UTC为“2018/05/04 1:00 PM”:
// Just creating the date. I assume you already have it, but this shows how to
// build one out of components.
NSDateComponents *comp = [NSDateComponents new];
comp.year = 2018;
comp.month = 5;
comp.day = 4;
comp.hour = 20;
comp.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
NSCalendar *gregorian = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
NSDate *date = [gregorian dateFromComponents:comp];
// Now format it
NSDateFormatter *form = [NSDateFormatter new];
form.timeZone = [NSTimeZone timeZoneWithName:@"PST"];
form.dateFormat = @"YYYY/MM/dd h:mm a";
NSString *string = [form stringFromDate:date]; // "2018/05/04 1:00 PM"
这就是说,您应该始终考虑是否使用本地化的日期格式化程序。它们并不总是适用,但它们会为您处理很多日期本地化问题。例如:
NSDateFormatter *form = [NSDateFormatter new];
form.timeZone = [NSTimeZone timeZoneWithName:@"PST"];
form.dateStyle = NSDateFormatterShortStyle;
form.timeStyle = NSDateFormatterShortStyle;
这将输出“5/4/18,下午1:00”
或使用本地化模板:
form.dateFormat = [NSDateFormatter dateFormatFromTemplate:@"YYYY/MM/dd h:mm a" options:0
locale:[NSLocale currentLocale]];
在美国,这将是“05/04/2018,下午1:00”,但在法国,它将是“04/05/2018à1:00 PM”。有时这很好,有时它不是你需要的,但知道它存在是很好的。
答案 1 :(得分:-1)
这就是我解决问题的方法。
int daylightOffsetSystem = [[NSTimeZone localTimeZone] daylightSavingTimeOffset];
int daylightOffsetForStartDate = [[NSTimeZone localTimeZone] daylightSavingTimeOffsetForDate:startDate];
BOOL isDaylightSavingTimeForStartDate = [[NSTimeZone localTimeZone] isDaylightSavingTimeForDate:startDate];
if (isDaylightSavingTimeForStartDate) {
if (daylightOffsetSystem == 0) {
localStartDate = [localStartDate dateByAddingTimeInterval:daylightOffsetForStartDate];
}
} else {
localStartDate = [localStartDate dateByAddingTimeInterval:-1*daylightOffsetSystem];
}
NSInteger tzOffset = [[NSTimeZone systemTimeZone] secondsFromGMT];
localStartDate = [localStartDate dateByAddingTimeInterval:tzOffset];