ТЛ; др
LocalDate
.now( ZoneId.of( "Pacific/Auckland" ) ) // Get the date-only value for the current moment in a specified time zone.
.minusWeeks( 1 ) // Go back in time one week.
.atStartOfDay( ZoneId.of( "Pacific/Auckland" ) ) // Determine the first moment of the day for that date in the specified time zone.
.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ) // Generate a string in standard ISO 8601 format.
.replace( "T" , " " ) // Replace the standard "T" separating date portion from time-of-day portion with a SPACE character.
java.time
Современный подход использует классы java.time.
Класс LocalDate
представляет значение только для даты без времени суток и без часового пояса.
Часовой пояс имеет решающее значение при определении даты. В любой момент времени дата меняется по всему земному шару в зависимости от зоны. Например, через несколько минут после полуночи в Париж Франция - это новый день, а еще «вчера» в Монреаль Квебек .
Укажите собственное имя часового пояса в формате continent/region
, например America/Montreal
, Africa/Casablanca
или Pacific/Auckland
. Никогда не используйте 3-4-буквенное сокращение, например EST
или IST
, так как они не истинные часовые пояса, не стандартизированы и даже не уникальны (!).
ZoneId z = ZoneId.forID( "America/Montreal" ) ;
LocalDate now = LocalDate.now ( z ) ;
Сделайте математику, используя методы minus…
и plus…
.
LocalDate weekAgo = now.minusWeeks( 1 );
Пусть java.time определит первый момент дня для вашего желаемого часового пояса. Не думайте, что день начинается с 00:00:00
. Аномалии, такие как переход на летнее время, означают, что день может начинаться в другое время суток, например 01:00:00
.
ZonedDateTime weekAgoStart = weekAgo.atStartOfDay( z ) ;
Создайте строку, представляющую этот объект ZonedDateTime
, используя объект DateTimeFormatter
. Поиск Переполнение стека для многих других дискуссий по этому классу.
DateTimeFormatter f = DateTimeFormatter.ISO_LOCAL_DATE_TIME ;
String output = weekAgoStart.format( f ) ;
Этот стандартный формат близок к тому, что вы хотите, но имеет T
в середине, где вы хотите пробел. Так замените ПРОБЕЛ на T
.
output = output.replace( "T" , " " ) ;
О java.time
Фреймворк java.time встроен в Java 8 и более поздние версии. Эти классы заменяют проблемные старые устаревшие классы даты и времени, такие как java.util.Date
, Calendar
, & SimpleDateFormat
.
Проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на классы java.time .
Чтобы узнать больше, см. Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .
Где взять классы java.time?
Joda-Time
Обновление: Проект Joda-Time сейчас находится в режиме обслуживания. Команда советует перейти на классы java.time.
Использование библиотеки Joda-Time значительно упрощает работу с датой и временем.
Обратите внимание на использование часового пояса. Если опущен, вы работаете в UTC или текущем часовом поясе JVM по умолчанию.
DateTime now = DateTime.now ( DateTimeZone.forID( "America/Montreal" ) ) ;
DateTime weekAgo = now.minusWeeks( 1 );
DateTime weekAgoStart = weekAgo.withTimeAtStartOfDay();