Я попытался преобразовать новый объект сегодняшней даты в UTC. Но не повезло, так как новый объект даты всегда находится в локальном часовом поясе. Я пытаюсь проверить две даты, используя метод "раньше". date1 находится в формате UTC. date2 сегодня.
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class test {
/**
* @param args
*/
public static void main(String[] args) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String todayStr = sdf.format(new Date());// This string is in UTC. But I need date object in UTC.
try {
System.out.println(sdf.parse(todayStr));// This is still printing in local time zone.
} catch (ParseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
Объект Date
не находится в часовом поясе - это всего лишь обертка вокруг количества миллисекунд с эпохи Unix. Эпоха Unix обычно описывается в терминах UTC (а именно, полночь в начале 1 января 1970 года), но это действительно только момент времени.
Чтобы получить момент за 48 часов до "сейчас", вы можете использовать что-то вроде:
Date earlier = new Date(System.currentTimeMillis() - TimeUnit.HOURS.toMillis(48));
Вы можете сравнить это с любым объектом Date
чтобы увидеть, что произошло раньше времени - опять же, без ссылки на какой-либо конкретный часовой пояс.
По правде говоря, это не легко проверяемое решение - я предпочитаю абстрагировать System.currentTimeMillis()
за интерфейсом Clock
, чтобы я мог протестировать с поддельными часами, установленными в любое время, которое я хочу.)
Если вам не требуется строковое представление, не обращайте на него внимания - как только вы хотите получить строковое представление, вам нужно подумать о том, какая система календаря и часовой пояс вам интересна.
Обратите внимание, что вы говорите о "сегодняшней дате" в вопросе - если вы имеете в виду начало определенного дня, то часовой пояс имеет значение, и вам нужно будет сделать больше работы.
Наконец, я бы предположил, что если возможно, вы используете либо java.time.*
Из Java 8, либо Joda Time, а не java.util.Date
и т.д. Первые два являются гораздо лучшими API, чем предыдущие.
В приведенном ниже коде всегда отображается текущий объект даты в локальном часовом поясе.
Да, это потому, что Date.toString()
использует локальный часовой пояс. Это то, что он делает (к сожалению), и это не значит, что объект Date
находится в локальном часовом поясе.
Подробные сведения см. В правильном ответе Джона Скита.
Ваше требование неясно, но, похоже, вы хотите проверить, соответствует ли целевая дата-строка дате времени, которая находится в течение 48-часового периода до начала сегодняшнего дня, как определено часовым поясом UTC. Другими словами, вчера или за день до этого.
java.util.Date
Избегайте использования классов java.util.Date и.Calendar в комплекте с Java. Они, как известно, хлопотно. Вместо этого используйте Joda-Time или новый java.time в Java 8 (вдохновленный Joda-Time). Обе библиотеки имеют класс времени, который знает свой собственный часовой пояс, в отличие от java.util.Date.
И обе библиотеки имеют классы для представления промежутка времени. Сравнение осуществляется с помощью метода "Half-Open", где начало является инклюзивным и окончательным исключением. Таким образом, ваш двухдневный период определяется как первый момент дня до вчерашнего дня (включительно) и заканчивается, но не включает в себя первый момент сегодняшнего дня (эксклюзивный).
Формат вашей строки определяется стандартом ISO 8601. И Joda-Time, и java.time используют ISO 8601 для дефолтов при разборе и генерации строк. Таким образом, у них есть встроенный форматтер для синтаксического анализа вашей строки. Просто передайте строку.
Joda-Time использует неизменяемые объекты. Вместо того, чтобы изменять ("мутировать") существующий объект, создается новый объект со значениями, основанными на оригинале. Причина в том, что безопасность потока.
Вот пример кода в Joda-Time 2.4.
DateTime target = new DateTime( "2014-01-02T03:04:05.789Z", DateTimeZone.UTC );
DateTime nowUtc = DateTime.now( DateTimeZone.UTC );
DateTime today = nowUtc.withTimeAtStartOfDay();
DateTime dayBeforeYesterday = today.minusDays( 2 ).withTimeAtStartOfDay();
Interval interval = new Interval( dayBeforeYesterday, today ); // Half-Open.
boolean hit = interval.contains( target );