java.util.Date: семь дней назад - PullRequest
       34

java.util.Date: семь дней назад

23 голосов
/ 04 февраля 2011

У меня есть отчет, созданный в Jasper Reports, который распознает ТОЛЬКО файл java.util.Date (не Calendar или Gregorian и т. Д.).

Есть ли способ создать дату за 7 дней до текущей даты?

В идеале это будет выглядеть примерно так:

new Date(New Date() - 7)

ОБНОВЛЕНИЕ: Я не могу подчеркнуть это достаточно: JasperReports НЕ ПРИЗНАЕТ объекты Java Calendar.

Ответы [ 11 ]

51 голосов
/ 04 февраля 2011

С этого момента:

long DAY_IN_MS = 1000 * 60 * 60 * 24;
new Date(System.currentTimeMillis() - (7 * DAY_IN_MS))

Из произвольного Date date:

new Date(date.getTime() - (7 * DAY_IN_MS))

Редактировать: Как указано в других ответах, не учитывает переход на летнее время, если это является фактором.

Просто чтобы прояснить то ограничение, о котором я говорил:

Для людей, затронутых переходом на летнее время , если под 7 days earlier, вы подразумеваете, что если сейчас значение равно 12pm noon on 14 Mar 2010, вы хотите, чтобы вычисление 7 days earlier привело в 12pm on 7 Mar 2010, тогда будьте осторожны.

Это решение находит дату / время ровно 24 часа * 7 дней = 168 часов раньше.

Однако некоторые люди удивляются , когда это решение обнаруживает, что, например, (14 Mar 2010 1:00pm) - 7 * DAY_IN_MS может вернуть результат в (7 Mar 2010 12:00pm), где время настенных часов в вашем часовом поясе не совпадает между 2 датой / временем (1pm против 12pm). Это происходит из-за перехода на летнее время, которое начинается или заканчивается той ночью, и из-за того, что «настенные часы» теряют или набирают час.

Если летнее время не является для вас фактором или если вы действительно хотите (168 hours) точно (независимо от смещения времени настенных часов), то это решение работает отлично.

В противном случае вам может потребоваться компенсация за то, что ваш 7 days earlier на самом деле не означает точно 168 часов (из-за начала или окончания летнего времени в течение этого периода).

27 голосов
/ 04 февраля 2011

Используйте функцию календаря для создания новых объектов Date, используя getTime():

import java.util.GregorianCalendar;
import java.util.Date;

Calendar cal = new GregorianCalendar();
cal.add(Calendar.DAY_OF_MONTH, -7);
Date sevenDaysAgo = cal.getTime();
13 голосов
/ 04 февраля 2011

1001 * попробовать *

 Date sevenDay = new Date(System.currentTimeMillis() - 7L * 24 * 3600 * 1000));

Другой способ - использовать Календарь, но мне самому не нравится.

9 голосов
/ 06 апреля 2016

Поскольку никто еще не упомянул TimeUnit:

new Date(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7))
5 голосов
/ 04 февраля 2011

Попробуйте это:

Calendar c = Calendar.getInstance();
c.add(Calendar.DAY_OF_MONTH, -7);
return c.getTime();
2 голосов
/ 19 июня 2014

Я не уверен, когда они добавили их, но JasperReports имеет свой собственный набор «функций», которые могут манипулировать датами.Вот пример, который я не проверял полностью:

DATE(YEAR(TODAY()), MONTH(TODAY()), DAY(TODAY()) - 7)

Это строит java.util.Date с датой, установленной на 7 дней с сегодняшнего дня.Если вы хотите использовать другую «якорную» дату, просто замените TODAY() на любую дату, которую вы хотите использовать.

1 голос
/ 21 июня 2014

Для определения «дней» требуется часовой пояс.Часовой пояс определяет, когда начинается «день».Часовой пояс включает в себя правила для перехода на летнее время и другие аномалии.Там нет магии, чтобы сделать часовые пояса неактуальными.Если вы игнорируете проблему, будет применен часовой пояс JVM по умолчанию.Это приводит к путанице и боли.

Избегайте java.util.Date

Классы java.util.Date и .Calendar, как известно, доставляют много хлопот.Избежать их.Они настолько плохи, что Sun / Oracle согласились заменить их новым java.time пакетом в Java 8. Используйте либо это, либо Joda-Time .

Joda-Time

Пример кода в Joda-Time 2.3.

DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" ); // Specify or else the JVM's default will apply.
DateTime dateTime = new DateTime( new java.util.Date(), timeZone ); // Simulate passing a Date.
DateTime weekAgo = dateTime.minusDays( 7 );

Первый момент дня

Или, возможно, вы захотите настроить время суток напервый момент дня, чтобы захватить ценность целого дня.Вызовите метод withTimeAtStartOfDay.Имейте в виду, что это обычно 00:00:00, но не всегда.

Избегайте "полуночных" методов и классов в Joda-Time.Они основаны на неверной концепции и теперь устарели.

DateTime dateTimeStart = new DateTime( new java.util.Date(), timeZone ).withTimeAtStartOfDay(); // Not necessarily the time "00:00:00".
DateTime weekAgo = dateTime.minusDays( 7 ).withTimeAtStartOfDay(); 

Преобразовать в / из juDate

Как видно выше, для преобразования из java.util.Date в Joda-Time просто передатьобъект Date для конструктора DateTime.Поймите, что у juDate нет часового пояса , у DateTime есть.Поэтому назначьте желаемый / подходящий часовой пояс для определения того, что такое «дни» и когда они начнутся.

Чтобы пойти другим путем, от DateTime к juDate, просто вызовите метод toDate.

java.util.Date date = dateTime.toDate();
0 голосов
/ 11 января 2019

Вы можете попробовать это,

    Calendar c = Calendar.getInstance();
    c.add(Calendar.DAY_OF_MONTH, -7);
    System.out.println(new java.sql.Date(c.getTimeInMillis()));
0 голосов
/ 06 октября 2017

Я делаю это так:

Date oneWeekAgo = DateUtils.addDays(DateUtils.truncate(new Date(), java.util.Calendar.DAY_OF_MONTH), -7);
0 голосов
/ 05 февраля 2011

Из-за жаркой дискуссии:

Вопрос может не иметь правильного ответа без обозначенного часового пояса.

ниже приведен код для работы с часовым поясом по умолчанию (и, следовательно, устаревшим), который учитывает летнее время по умолчанию для часового пояса.

Date date= new Date();
date.setDate(date.getDate()-7);//date works as calendar w/ negatives

Хотя решение работает,точно так же фиктивно, как и с точки зрения предположения о часовом поясе.

new Date(System.currentTimeMillis() - 10080*60000);//a week has 10080 minutes

Пожалуйста, не голосуйте за ответ.

...