Получить отметку времени для начала дня

Я храню время/даты в базе данных, используя временную метку unix. Затем я хочу получить все экземпляры в определенный день, поэтому мне нужно вычислить временную метку для начала дня, чтобы запросить базу данных.

Я сделал аналогичную вещь в php, передав mktime значения для дня/месяца/года из объекта даты и установив час и минуту на ноль. Кажется, что в java/android не работают аналогичные функции (функции для получения определенных частей даты устарели)

Может ли кто-нибудь дать некоторые рекомендации по этому поводу? благодаря

Редактировать:

Хорошо, поэтому я понял, что это может сработать:

public static int startOfDay(Timestamp time) {
        Calendar cal = dateToCalendar(new Date(time.getTime()));
        cal.add(Calendar.HOUR_OF_DAY, -Calendar.HOUR_OF_DAY);
        cal.add(Calendar.MINUTE, -Calendar.MINUTE);
        cal.add(Calendar.SECOND, -Calendar.SECOND);
        Log.i("Time", cal.getTime().toString());        
        return (int) cal.getTimeInMillis()/1000;
}

Однако когда я запустил это сейчас, я получил:

Сб Дек 15 01:24:00 GMT 2012

Секунды правильные, но час и минута неправильны?

Ответ 1

При работе со временем вы всегда должны учитывать часовые пояса. Временные метки базы данных всегда должны храниться в одном часовом поясе (например, в формате UTC). Затем ваши вычисления должны учитывать, что пользователи могут находиться в разных часовых поясах и что они могут изменять часовые пояса.

Если вы хотите вычислить начало дня в часовом поясе, который пользователь установил в своем телефоне. Создайте экземпляр Calendar с помощью:

Calendar cal = Calendar.getInstance(); 

Чтобы получить экземпляр для определенного часового пояса, используйте:

// use UTC time zone
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));

Затем установите начало дня:

cal.setTime(time); // compute start of the day for the timestamp
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);

Ответ 2

public static int startOfDay(Timestamp time) {
    Calendar cal = Calendar.getInstance();
    cal.setTimeInMillis(time.getTime());
    cal.set(Calendar.HOUR_OF_DAY, 0); //set hours to zero
    cal.set(Calendar.MINUTE, 0); // set minutes to zero
    cal.set(Calendar.SECOND, 0); //set seconds to zero
    Log.i("Time", cal.getTime().toString());        
    return (int) cal.getTimeInMillis()/1000;
}

Ответ 3

ТЛ; др

ZoneId z = ZoneId.of( "America/Montreal" );
long secondsSinceEpoch = ZonedDateTime.now( z ).toLocalDate().asStartOfDay( z ).toEpochSecond() ;

Детали

Принятый ответ Томика правильный, но устаревший. Классы java.time вытеснили старые классы устаревших дат.

Как сказано в этом ответе, вы должны учитывать часовой пояс, когда начинаете день. Часовой пояс имеет решающее значение для определения даты. В любой данный момент дата изменяется по всему миру по зонам. Например, через несколько минут после полуночи в Париже Франция - новый день, еще "вчера" в Монреале Квебек.

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.now( z );

Получение первого момента дня требует прохождения через LocalDate. Класс LocalDate представляет значение даты только без времени и без часового пояса.

LocalDate today = zdt.toLocalDate();
ZonedDateTime zdtTodayStart = today.atStartOfDay( z );

Обратите внимание, что мы разрешаем java.time определять начало дня, а не предполагать и жестко кодировать 00:00:00. Из-за летнего времени (DST) и других аномалий день может начинаться в другое время, например, 01:00:00.

По-видимому, по unix timestamp вы имеете в виду подсчет целых секунд с первого момента 1970 года в UTC. Класс ZonedDateTime имеет способ предоставить вам это число. Обратите внимание, что это может означать потерю данных, поскольку ZonedDateTime может иметь долю секунды с разрешением наносекунд.

long secondsSinceEpoch = zdtTodayStart.toEpochSecond();

О java.time

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

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

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

Большая часть функциональных возможностей java.time была перенесена на Java 6 и 7 в ThreeTen-Backport и далее адаптирована для Android в ThreeTenABP (см. Как использовать...).

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