1. Conhecimento de preparação
1. O horário de verão da América/New_York é o seguinte: a esquerda não é a direita é
2016-3-13, 02:00:00 a 2016-11-6, 02:00:00
2017-3-12, 02:00:00 a 2017-11-5, 02:00:00
2. ID do fuso horário de três letras
Para compatibilidade com o JDK 1.1.x, alguns IDs de fuso horário de três letras (como "PST", "CTT", "AST") também são suportados.
No entanto, seu uso é descartado porque a mesma abreviação é frequentemente usada em vários fusos horários
Por exemplo, CST: tem 4 significados, Estados Unidos, Austrália, China, Cuba Time
3. Padrão
GMT: Verde Time médio Greenwich Time, foi usado como referência de tempo padrão GMT+12-> GMT-12 antes de 1960
A faixa de Java8 é GMT+18-> GMT-18
UTC: O tempo universal coordenado coordena o tempo mundial, que é mais preciso que o GMT, e se torna o novo padrão em 1º de janeiro de 1972; UTC, UTC+1, UTC+2 ... UTC+12, UTC-12 ... UTC-1
Range UTC-18 do Java8-> UTC+18
DST: o horário de verão refere -se ao tempo em que o relógio é aparecendo por uma hora no verão para usar a luz do sol mais cedo. É chamado de verão no Reino Unido;
Atualmente, mais de 110 países usam o horário de verão;
Na China, foi implementado apenas por 6 anos de 1986 a 1992, e foi cancelado posteriormente; As razões são as seguintes:
1. A China tem uma grande extensão nas direções leste e oeste e adota um oitavo distrito leste unificado, que é incompatível com o leste e oeste, usando o horário de verão;
2. Em áreas de alta latitude, a hora do dia e da noite muda muito no inverno e no verão; Não é muito significativo;
4. Pode ser usado para indicar que o Oitavo Distrito Leste é: GMT+8 ou etc/GMT-8 (o contrário, por quê? Porque os desenvolvedores do PHP acreditam que o oitavo distrito leste é 8 horas mais rápido que o tempo padrão e deve ser subtraído por 8 horas; portanto, a representação é assim. Objetos de referência diferentes para os diferentes métodos de representação;
5. Como representar o fuso horário da China
GMT+8
UTC+8
Ásia/Harbin Harbin // China Standard Time
Ásia/Chongqing Chongqing // China Standard Time
Ásia/Chungking Chongqing // China Standard Time
Ásia/Urumqi Urumqi // China Standard Time
Ásia/Shanghai Shanghai (Distrito do Leste 8) // China Standard Time
Prc
Ásia/Macau Macau // China Standard Time
Hong Kong Hong Kong // O tempo de Hong Kong é consistente com o tempo padrão da China
Ásia/Hong_kong Hong Kong
Ásia/Taipei Taipei (Taiwan) // China Standard Time Singapore é o mesmo que o tempo da China;
Ásia/Cingapura
Cingapura
6. Representação de fusos horários padrão
UTC
UTC+0
UTC-0
GMT GMT
GMT0 GMT
Etc/gmt gmt
Etc/gmt+0 gmt
Etc/gmt-0 gmt
Etc/gmt0 gmt0 gmts hime time Nota: GMT+xx (-xx) é muito inclusivo e pode identificar automaticamente a representação de vários tempos.
2. Conversão de fuso horário
Ambiente: Antes de Java8
1. Converta o horário atual para a exibição do fuso horário especificado
@Test public void test () lança Exceção {date a = new Date (); SimpledateFormat SF = new SimpleDateFormat ("AAAA-MM-DD HH: MM: SS"); sf.setTimeZone (TimeZone.GetTimeZone ("America/New_York")); // Converta o fuso horário chinês para o fuso horário de Nova York do sistema dos Estados Unidos.out.println (sf.format (a)); }2. O tempo especificado é convertido para a exibição especificada do fuso horário
Posso realmente converter corretamente? Parece haver uma armadilha, olhei para a implementação online
Sinto um pequeno problema com o horário de verão
// Método de implementação 1: O tempo de economia do dia não é considerado @test public void test2 () lança Exceção { /date dateTime = new SimpleDateFormat ("AAAA-MM-DD HH: MM: SS"). Parse ("2016-11-6 14:00:00"); Data DateTime = New SimpleDateFormat ("AAAA-MM-DD HH: MM: SS"). Parse ("2016-10-6 14:00:00"); Zona time zhong = timezone.getTimeZone ("GMT+8: 00"); // China Timebone York = TimeZone.GetTimeZone ("America/New_York"); // GMT-5 // O deslocamento do fuso horário aqui é corrigido, não há tempo de economia de luz, erro longo chinesemills = dateTime.getTime () + york.getrawoffset ()-zhong.getrawoffset (); Data data = nova data (chinesemills); System.out.println (new SimpleDateFormat ("AA YYYY-MM-DD HH: MM: SS"). Formato (DATE)); } // Método de implementação 2 Você pode se lembrar de que, usando calendar.dst_offset da classe do calendário // ainda não é certo calendário.dst_offset Este é Dead @testpublic void test3 () lança excepção {// date time = new SimpleFormat ("yyyyy-mm-dd hh: mm: ss"). SimpledateFormat ("AAAA-MM-DD HH: MM: SS"). Hh: mm: ss "). HH: mm: ss "). cal.get (calendar.zone_offset)/(1000*60*60); // 3. Obtenha a diferença de horário de economia do dia: isso é corrigido, não com base no julgamento dinâmico do tempo. Enquanto houver um tempo de economia de luz no fuso horário, é 1INT dSToffset = Cal.get (calendar.dst_offset)/(1000*60*60); System.out.println (zoneoffset); System.out.println (dstoffset); // 4. Deduz essas diferenças do tempo local ao tempo. -(Zoneoffset + dstoffset)); cal.add (calendar.hour, -(zoneoffset + dstoffset)); data time2 = cal.gettime (); system.out.println (new SimpleDateFormat ("yyyyy -mm -dd hh: mm: ss"). // Método de implementação 3 Preparação // Não diz que o Java lidará automaticamente com o horário de verão para nós? // Vamos primeiro ter um teste simples para ver se o método de julgamento do horário de verão está correto e você pode inferir se o processamento automático de Java está correto // Sabe-se que em 2016: tempo de economia do dia da América/New_york »Time de RENUSTIONS IS: 01-3-13 02:00 a 2016-11-06 01:59:59 @ SimpledateFormat SF = new SimpleDateFormat ("AAAA-MM-DD HH: MM: SS"); sf.setTimeZone (TimeZone.GetTimeZone ("GMT+0")); // Data DateTime = Sf.parse ("2016-11-6 5:59:59"); DATA D1 = SF.PARSE ("2016-03-13 6:59:59"); // Data falsa d2 = sf.parse ("2016-03-13 7:00:00"); // Data True d3 = sf.parse ("2016-11-6 6:59:59"); descobriu que, de fato, não há problema em julgar o início do horário de verão, mas durante o horário de fim de verão, para ser preciso, eu o julguei com uma hora de antecedência // Olhe para a verificação abaixo, então por que tem uma hora de antecedência? Como resolvê -lo? Atualmente, só posso usar java8 d3 = sf.parse ("2016-11-6 5:59:59"); // true d4 = sf.parse ("2016-11-6 6:00:00"); // FALSO TEMPOZONE YORK = TimeZone.GetTimeZone ("America/New_York"); // GMT-5 System.out.println ("O fuso horário alvo usa o horário de verão:"+Isdaylight (York, D1)); System.out.println ("O fuso horário alvo usa o horário de verão:"+Isdaylight (York, D2)); System.out.println ("O fuso horário de destino usa o horário de verão:"+Isdaylight (York, D3)); System.out.println ("O fuso horário alvo usa o horário de verão:"+Isdaylight (York, D4)); } // julga se private boolean isdaylight (zona do fuso horário, data de data) {return zone.uselaylighttime () && zone.indaylighttime (data); } // Método de implementação 3 // Através da verificação acima, sabemos que o julgamento do sistema é problemático. Ao definir o fuso horário, o programa lida automaticamente no horário de verão. Pelo menos não consigo entender por que o @TestPublic void test5 () lança exceção {// 13 horas de diferença na China + 8 Nova York-5 Changezone ("2016-3-13 14:59:59", "PRC", "America/New_york", "YYYY-MM-DD HH: MM: SS"); 15:00:00", "PRC","America/New_York", "yyyy-MM-dd HH:mm:ss");//2016-03-13 03:00:00 ChangeZone("2016-11-6 13:59:59", "PRC","America/New_York", "yyyy-MM-dd HH:mm:ss");//2016-11-06 01:59:59 // Este resultado está errado, deve ser 02:00:00 ChangeZone ("2016-11-6 14:00:00", "PRC", "America/New_york", "AAA11:yyy-dd HH: MM: SS"); //16-11-06 01:00:00} // tempo, string srcid, string Destid, String Pattern) lança parseException {// Defina o fuso horário do fuso horário padrão = zone timeZone.getTimeZone (srcid); Timezone.setDefault (zona); Data data = new SimpleDateFormat (padrão) .parse (hora); // Defina o fuso horário do fuso horário de destino DestZone = TimeZone.GetTimeZone (Destid); SimpledateFormat sdf = new SimpleDateFormat (padrão); // defina o fuso horário para ser formatado sdf.setTimeZone (Destzone); String changtime = sdf.format (data); // Obtenha o System.out.println ("Após modificar o fuso horário" + Destzone.getId () + "Time:" + ChangTime); }Resumo: Os resultados obtidos pelos três métodos de implementação acima são um tanto problemáticos para o horário de verão
Três, implementação Java8
1. Vamos dar uma olhada nas mudanças no fuso horário no Java 8 primeiro
// JDK8 Disponível fuso horário @testpublic void testName1 () lança Exceção {// JDK8 SET FUSE DO TEMPO <String> ids = zoneId.GetAVALABLEZONEIDS (); string [] iD1 = ids.toArray (new String [Ids.size ()); String IDSS = Arrays.OSSSSSSOS (strings.s.size ();); string) = arrays.ssosSoss.ToArray (new String [). ",]"); System.out.println (ids.size ()); // 28 fusos horários ausentes antes da string do JDK8 [] id2 = timezone.getAvailableIds (); system.out.println (id2.length); //623//Find out the for (String id: id2) {if (!idss.contains(id+",")) {System.out.print(id+",");}}//Conclusion: All time zones in jdk8 have all been deleted before //jdk8 as follows: //There are some time zones that are easily ambiguous// EST, HST, MST, ACT, AET, AGT, ART, AST, BET, BST, CAT, CNT, CST, CTT, EAT, ECT, IET, IST, JST, MIT, NET, NST, PLT, PNT, PRT, PST, SST, VST, // Mas esses nomes curtos ainda estão disponíveis, eles simplesmente não estão disponíveis na lista de suporte local local =/ LocalDateTime.ofinstant (instant.now (), zoneid.of (zoneid.short_ids.get ("pst"))); system.out.println ("/ndate =" + date);}2. Como adicionar informações sobre o fuso horário ou convertê -las
// LocalDate, LocalDateTime, Instant Adicione informações do fuso horário @TestPublic void testName3 () {LocalDate Date = localDate.now (); // localDate Adicione informações do fuso horário // Método 1ZONEDDATETime Zona = Date.atstartOfday (ZoneId.Of ("GMT+08: 00"); date.atstartofday (zoneId.systemDefault ()); System.out.println (zone); // Método 2 LocalDate Date2 = LocalDate.now(ZoneId.of("GMT+0"));System.out.println(date2);System.out.println("----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ zoneime3 = localDateTime.now (clock.system (zoneid.of ("gmt+0"))); // Método 4ZONEDDATETIMETIMENTE ZoneNetime4 = zonedDateTime.of (tempo, zonetime.of ("gmt+0"); system.out.println (zonetime); System.out.println (zonetime3); // altere o sistema.out.println (zonetime4); // alteração System.out.println ("----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------3. Como obter o tempo especificado da hora atual (teste omitido)
// Obtenha o fuso horário especificado do horário atual, ponto de referência: 0 furo horário público localDateTime getCurrentZoNetime (zoneId dest) {objects.requiirononnull (dest); LocalDateTime Time2 = LocalDateTime.now (Clock.system (dest)); String zonedesc = getZoneDesc (timezone.getTimeZone (dest)); System.out.println (dest.getId ()+"corresponde ao fuso horário padrão:"+zonedesc); System.out.println ("fuso horário de destino"+dest+"time"+time2.Format (DateTimeFormatter.ofPattern ("yyyy-mm-dd hh: mm: ss"))); tempo de retorno2;} // Obter fuso horário padrão, método 1 // o método Antes do JDK8, use o fuso horário privado String estático getZoneDesc (fuso horário DestZone) {Objects.RequiRononNull (Destzone); int offset = Destzone.getrawoffset () / (1000 * 60 * 60); if (deslocamento <= 0) {return "gmt"+string.valueof (deslocamento); } else {return "gmt +" + string.valueof (deslocamento); }} // Java8 Método, Método 2, use Zoneles // Obtenha o deslocamento padrão do fuso horário, Zonerules.GetStandardOffset // Obtenha o deslocamento real do fuso horário (o deslocamento obtido será alterado de acordo com a luz do dia) // O deslocamento padrão do fuso do tempo (o desvio resultante será alterado de acordo com o dia da luz do dia) // O deslocamento do tempo resultante do tempo resultante de acordo com a luz do dia) // regra.getStandardOffset (zonedDateTime.now (dest) .ToinStant ()). getId (); String S = StandardOffset.split (":") [0]; int offset = Integer.parseint (s); // Método de retorno 1: com horas e minutos // retorna "gmt"+standardoffset; // Método de retorno 2: com horas somente se (deslocamento> 0) {return "gmt+"+offset;} else {return "gmt"+offset;}}4. Como obter o tempo especificado do fuso horário especificado
Comece a implementar o problema do fuso horário deixado acima
Da mesma forma, vamos primeiro analisar se o método de julgamento do horário de verão usando o Java8 está correto.
// Escreva uma mão em primeira mão para determinar se o tempo nos Estados Unidos está no dia de economia de tempo público booleano isdaylightTime (LocalDateTime A) {Objects.RequiReNononlul (a); LOCALDATETIME STARTDATE = A.ChiMmonth (3) .tolocaldate (). Attime (2, 0); LocalDateTime startlightday = startDate.with (temporaladjusters.dayofweekinmonth (2, Dayofweek.sunday)); // Atualize para novembro LocalDateTime EndDate = A.ChiThmonth (11) .Tolocaldate (). Forness (1, 59,59); LocalTime -EndMay enddate.with (temporaladjusters.dayofweekinmonth (1, Dayofweek.sunday)); if (a.sbefore (startlightday) || a. Java8 já existe um método pronto, que é melhor que o meu // passa no interno e no fuso horário especificado IsdaylightTime (LocalDateTime A, ZoneId dest) {ZonedDateTime Z1 = A.Atzone (dest); // ou transfira dessa maneira // zonedDateTime Z2 = zonedDateTime.of (a, dest); System.out.println (z1.format (DateTimeFormatter.ofPattern ("AAAA-MM-DD HH: MM: SS"))); Regras de zonerules = dest.getRules (); bandeira booleana = regras.isdaylightSavings (z1.toinstant ()); System.out.println (sinalizador); sinalizador de retorno; }// Testá -lo e descobriu que o método de tempo de economia de luz do dia de Java8 está completamente correto
// Sabe-se que 2016: America/New_York O horário de verão é: 2016-3-13 02:00:00 para 2016-11-06 01:59:59 // (o segundo domingo de março e o primeiro domingo de novembro) @testpublic void testname () lança exceção {// localDatETTime A1 = Localdatime. LocalDateTime A2 = LocalDateTime.of (2016, 3, 13, 1, 59,59); LocalDateTime A3 = LocalDateTime.Of (2016, 3, 13, 2, 00); LocalDateTime A4 = LocalDateTime.Of (2016, 11, 6, 1, 59,59); LocalDateTime A5 = LocalDateTime.of (2016, 11, 2, 2, 2, 0,0); // isdaylighttime (a2); // isdaylighttime (a3); // isdaylightTime (a4); // isdaylighttime (a5); system.out.println ("========================================= ========================================================================= ========================================================================= ========================================================================= ========================================================================= ========================================================================= ========================================================================= ); // falseSdaylightTime (a3, zoneid.of ("America/new_york")); // TrueisdaylightTime (a4, zoneid.of ("America/New_york")); // Trueisdaylighttime (A5, zoneid.of ("America/New_york"); // Fasle}Comece a implementar:
Versão 1:
// Obtenha o ponto de referência de tempo especificado para o tempo especificado: fuso horário padrão Public LocalDateTime GetzongTime (tempo localDateTime, zoneID dest) {Objects.ReQuirOnNonull (dest); retornar getzongtime (tempo, nulo, dest); } // Você não pode subtrair o ZonedDateTime de 2 fusos horários, porque depois de especificar o fuso horário aqui, esse tempo é esse fuso horário localDateTime GetzongTime (tempo localDeTime, ZoneID SRC, ZoneId dest) {// A dificuldade é como encontrar os Estados Unidos. Provavelmente, isso é mais adequado para objetos.RequirenOnNull (dest); ZonedDateTime Z1 = nulo; if (src == null) {z1 = time.atzone (zoneId.systemDefault ()); } else {z1 = time.atzone (src); } // A resposta do fuso horário muda no tempo zonedDateTime Z2 = z1.withZonesameInstant (dest); System.out.println (dest.getId ()+"corresponde ao fuso horário padrão:"+getZoneDesc (timezone.getTimeZone (dest))); System.out.println ("Fuso de fuso horário de destino"+dest+"time"+z2.Format (DateTimeFormatter.ofPattern ("yyyy-mm-dd hh: mm: ss"))); System.out.println ("---------------"); tempo de retorno; }O teste é o seguinte:
@Test public void test6 () lança a exceção {// Espera-se que não esteja no dia de verão Time2016-03-13 01:59:59 LocalDateTime Time4 = localDateTime.Of (2016, 3, 13, 14, 59, 59); getzongTime (time4, zoneid.of ("America/new_york")); // Espera-se que esteja no horário de verão TIME2016-03-13 03:00:00 LocalDateTime Time1 = localDateTime.Of (2016, 3, 13, 15, 00, 00); getzongTime (time1, zoneid.of ("America/new_york")); //The expected result in daylight saving time: 2016-11-06 01:59:59 //I feel like it failed again, it should be 2016-11-06 02:59:59 //In other words, the method before java8 handles the end of daylight saving time at this time is exactly the same, and judges one hour in advance //That is, the end time of daylight saving time is regarded as 2016-11-6 00:59:59, mas o método de julgamento de Java8 está correto. Não é um pouco estranho LocalDeTime Time2 = LocalDateTime.of (2016, 11, 6, 14, 59, 59); getzongTime (time2, zoneid.of ("America/new_york")); // Não é esperado que esteja no dia a salvar Time2016-11-06 02:00:00 LocalDateTime Time3 = LocalDateTime.Of (2016, 11, 6, 15, 00, 00); getzongTime (time3, zoneid.of ("America/new_york")); }Então, agora duvido que esse resultado seja um problema de cálculo sistemático ou não entendo a costume de Nova York?
Mas ainda posso obter os resultados que quero, use 2 métodos:
WithEarlierOffSetatoverlap (), WithLateroffsetatoverlap ()
Versão 2:
// Obtenha o ponto de referência de tempo especificado para o tempo especificado: fuso horário padrão público localDateTime getzongTime2 (tempo localDateTime, zoneId dest) {objects.requiirenOnnull (dest); retorna getzongTime2 (time, null, dest);} // versão 2 localDateTimeTime Offset // O fuso horário padrão é usado aqui, na China, nos Estados Unidos, os Estados Unidos são os Estados Unidos, por isso é provavelmente mais adequado para objetos. ZonedDateTime Z1 = nulo; if (src == null) {z1 = time.atzone (zoneId.systemDefault ()); } else {z1 = time.atzone (src); } // zonedDateTime Z2 = z1.withZonesameInstant (dest); // manipula problemas sobrepostos longas horas = duração. z2 = z2.plushours (horas); System.out.println (dest.getId ()+"corresponde ao fuso horário padrão:"+getZoneDesc (timezone.getTimeZone (dest))); System.out.println ("Fuso de fuso horário de destino"+dest+"time"+z2.Format (DateTimeFormatter.ofPattern ("yyyy-mm-dd hh: mm: ss"))); System.out.println ("-----------------"); tempo de retorno;}Teste: OK
@Test public void test4 () lança a exceção {// Espera-se que não esteja no dia de verão Time2016-03-13 01:59:59 LocalDateTime Time4 = localDateTime.Of (2016, 3, 13, 14, 59, 59); getzongTime2 (time4, zoneid.of ("America/new_york"); // Espera-se que esteja no horário de verão TIME2016-03-13 03:00:00 LocalDateTime Time1 = localDateTime.Of (2016, 3, 13, 15, 00, 00); getzongTime2 (time1, zoneid.of ("America/new_york"); // Espera-se que esteja no horário de verão 2016-11-06 02:59:59 LocalDateTime Time2 = LocalDateTime.Of (2016, 11, 6, 14, 59, 59); getzongTime2 (time2, zoneid.of ("America/new_york"); // Espera-se não no horário de verão 2016-11-06 02:00:00 LocalDateTime Time3 = localDateTime.Of (2016, 11, 6, 15, 00, 00); getzongTime2 (time3, zoneid.of ("America/new_york"); }resultado:
América/new_york corresponde ao fuso horário padrão: GMT-5
Hora do fuso horário-alvo America/new_york 2016-03-13 01:59:59
------------------------
América/new_york corresponde ao fuso horário padrão: GMT-5
Hora do fuso horário-alvo America/new_york 2016-03-13 03:00:00
------------------------
América/new_york corresponde ao fuso horário padrão: GMT-5
Hora do fuso horário-alvo America/new_york 2016-11-06 02:59:59
------------------------
América/new_york corresponde ao fuso horário padrão: GMT-5
Hora do fuso horário-alvo America/new_york 2016-11-06 02:00:00
------------------------
O problema e a solução acima para converter o horário de verão com base no fuso horário do Java é todo o conteúdo que compartilho com você. Espero que você possa lhe dar uma referência e espero que você possa apoiar mais o wulin.com.