Алгоритм определения летнего времени на дату? - PullRequest
2 голосов
/ 16 сентября 2008

Изначально я ищу решение в Actionscript. Суть этого вопроса - алгоритм, который определяет точную минуту, когда часы должны переключать летнее время.

Так, например, между 25 и 31 октября мы должны проверить, является ли фактическая дата воскресеньем, до или после 2 часов ...

Ответы [ 2 ]

4 голосов
/ 01 октября 2008

Реального алгоритма для перехода на летнее время не существует. В принципе, каждая страна может решить для себя, когда и когда DST начинается и заканчивается. Единственное, что мы можем сделать как разработчики, это использовать какую-то таблицу для ее поиска. Большинство компьютерных языков интегрируют такую ​​таблицу в язык.

В Java вы можете использовать метод inDaylightTime класса TimeZone . Если вы хотите узнать точную дату и время начала или окончания летнего времени в определенном году, я бы порекомендовал использовать Joda Time . Я не вижу чистого способа выяснить это, используя только стандартные библиотеки.

Следующая программа является примером: (Обратите внимание, что она может дать неожиданные результаты, если в определенном часовом поясе нет летнего времени в течение определенного года)

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;

public class App {
    public static void main(String[] args) {
        DateTimeZone dtz = DateTimeZone.forID("Europe/Amsterdam");

        System.out.println(startDST(dtz, 2008));
        System.out.println(endDST(dtz, 2008));
    }

    public static DateTime startDST(DateTimeZone zone, int year) {
        return new DateTime(zone.nextTransition(new DateTime(year, 1, 1, 0, 0, 0, 0, zone).getMillis()));
    }

    public static DateTime endDST(DateTimeZone zone, int year) {
        return new DateTime(zone.previousTransition(new DateTime(year + 1, 1, 1, 0, 0, 0, 0, zone).getMillis()));
    }
}
1 голос
/ 24 мая 2018

Ответ Рихтерса правильный и должен быть принят.

Как заметил Рихтерс, логики для перехода на летнее время (DST) или других аномалий нет. Политики произвольно переопределяют смещение от UTC , используемое в их часовых поясах . Они вносят эти изменения часто с небольшим предупреждением или даже без предупреждения, как Северная Корея сделала несколько недель назад.

java.time

Вот некоторые дополнительные мысли и пример кода с использованием современных java.time классов, которые следовали за классами Joda-Time, показанными в его Ответе.

Эти изменения отслеживаются в списке, поддерживаемом ICANN , известном как tzdata , ранее известном как база данных Olson. Ваша реализация Java, операционная система хоста и система базы данных, скорее всего, имеют свои собственные копии этих данных, которые необходимо заменять по мере необходимости, когда изменения происходят в режимах, которые вас интересуют. В этих изменениях нет логики, поэтому нет способа предсказать изменения программно. Ваш код должен вызывать свежую копию tzdata .

Так, например, между 25 и 31 октября мы должны проверить, является ли фактическая дата воскресеньем, до или после 2 часов ...

На самом деле вам не нужно определять точку отсечки. Хорошая библиотека времени и даты обрабатывает это автоматически.

Java обладает лучшими подобными библиотеками, ведущими в отрасли java.time классами. Когда вы запрашиваете время суток в определенную дату в определенном регионе (часовом поясе), если это время суток недопустимо, корректировка выполняется автоматически. Прочитайте документацию по ZonedDateTime, чтобы понять алгоритм, использованный в этой настройке.

ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate ld = LocalDate.of( 2018 , Month.MARCH , 11 );  // 2018-03-11.
LocalTime lt = LocalTime.of( 2 , 0 );  // 2 AM.
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z );

Обратите внимание, что результат - 3 часа ночи, а не запрошенный 2 часа ночи. В тот день в этой зоне не было двух часов ночи. Так что java.time настроен на 3 часа ночи, так как часы «Спрингс впереди» час.

zdt.toString (): 2018-03-11T03: 00-04: 00 [Америка / Монреаль]

Если вы чувствуете необходимость исследовать правила, определенные для часового пояса, используйте класс ZoneRules.

Получите величину сдвига DST, использованного в настоящий момент.

Duration d = z.getRules().getDaylightSavings​( Instant.now() ) ;

Получить следующее запланированное изменение, представленное в виде объекта ZoneOffsetTransition.

ZoneId z = ZoneId.of( "America/Montreal" );
ZoneOffsetTransition t = z.getRules().nextTransition( Instant.now() );
String output = "For zone: " + z + ", on " + t.getDateTimeBefore() + " duration change: " + t.getDuration() + " to " + t.getDateTimeAfter();

Для зоны: Америка / Монреаль, с 2018-11-04T02: 00 изменение продолжительности: с PT-1H на 2018-11-04T01: 00

Укажите собственное имя часового пояса в формате continent/region, например America/Montreal, Africa/Casablanca или Pacific/Auckland. Никогда не используйте 3-4-буквенное сокращение, например EST или IST, поскольку они не истинные часовые пояса, не стандартизированы и даже не уникальны (!).


О java.time

Фреймворк java.time встроен в Java 8 и более поздние версии. Эти классы заменяют проблемные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar, & SimpleDateFormat.

Проект Joda-Time , теперь в режиме обслуживания , рекомендует выполнить переход на классы java.time .

Чтобы узнать больше, см. Учебное пособие по Oracle . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .

Вы можете обмениваться java.time объектами напрямую с вашей базой данных. Используйте драйвер JDBC , совместимый с JDBC 4.2 или более поздней версии. Нет необходимости в строках, нет необходимости в java.sql.* классах.

Где получить классы java.time?

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти несколько полезных классов, таких как Interval, YearWeek, YearQuarter и more .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...