objective c - que - ¿Por qué NSDateFormatter devuelve una fecha nula para estas 4 zonas horarias?
para que sirven los husos horarios (2)
Créditos a Jon Skeet por ponerme en el camino correcto. Sin embargo, solo quiero aclarar su respuesta en un contexto iOS.
Cuando solicita a NSDateFormatter que convierta un número de día juliano en un NSDate, solo puede especificar números enteros (generalmente puede especificar una parte decimal para las horas / minutos / segundos del día) en la cadena que se analizará. Debido a que Apple demarca los días julianos a la medianoche (a diferencia del mediodía en astronomía, lea más aquí: http://www.unicode.org/reports/tr35/#Date_Field_Symbol_Table ) y algunos midnights simplemente no existen (gracias por señalar eso @JonSkeet) NSDateFormatter identifica que ese punto particular en el tiempo no existe en esa zona horaria y devuelve nil.
Para el registro, iOS5 no se comporta así y estoy de acuerdo con Jon Skeet, que NSDateFormatter debería devolver un NSDate ajustado para DST en lugar de cero, ya que ese día juliano en particular existe. Archivé un error con Apple.
Intenta ejecutar esto en iOS6 (no lo he probado antes de iOS6):
NSDateFormatter *julianDayDateFormatter = nil;
julianDayDateFormatter = [[NSDateFormatter alloc] init];
[julianDayDateFormatter setDateFormat:@"g"];
for (NSString *timeZone in [NSTimeZone knownTimeZoneNames]) {
julianDayDateFormatter.timeZone = [NSTimeZone timeZoneWithName: timeZone];
NSDate *date = [julianDayDateFormatter dateFromString:[NSString stringWithFormat:@"%d", 2475213]];
if (date == nil)
NSLog(@"timeZone = %@", timeZone);
}
y obtienes el siguiente resultado:
America/Bahia
America/Campo_Grande
America/Cuiaba
America/Sao_Paulo
¿Alguien puede explicar por qué estas cuatro zonas horarias se comportan así con NSDateFormatter establecido en números de día julianos? Todas las demás zonas horarias hacen que NSDateFormatter devuelva NSDates reales.
Tengo una sospecha . Solo una sospecha, pero bastante fuerte.
Ese valor representa el 19 de octubre de 2064. Las zonas horarias brasileñas observan el horario de verano a partir de la medianoche local , es cuando sus relojes avanzan, por lo que la medianoche misma no existe. El 19 de octubre es una de esas transiciones.
Aquí hay algunos ejemplos de código que usan Noda Time, mi API .NET de fecha / hora. Comprueba si el comienzo del día en cada zona horaria que conoce es en realidad medianoche:
using System;
using NodaTime;
class Test
{
static void Main()
{
var localDate = new LocalDate(2064, 10, 19);
var provider = DateTimeZoneProviders.Tzdb;
foreach (var id in provider.Ids)
{
var zone = provider[id];
var startOfDay = zone.AtStartOfDay(localDate).LocalDateTime.TimeOfDay;
if (startOfDay != LocalTime.Midnight)
{
Console.WriteLine(id);
}
}
}
}
Eso produce una lista muy similar:
America/Bahia
America/Campo_Grande
America/Cuiaba
America/Sao_Paulo
Brazil/East
Sospecho que Brasil / Este puede ser un alias para América / Sao_Paolo, por lo que no está en su lista.
De todos modos, para volver a tu problema del día juliano, sospecho que el formateador siempre quiere devolver un NSDate *
que se encuentra en la medianoche local. Eso no existe para el 19 de octubre de 2064 en esas zonas horarias ... por lo tanto, devuelve nada. Personalmente, sugeriría que devuelva el valor de la 1am, pero oye ...