Как получить первый день текущей недели и месяца?
У меня есть дата нескольких событий, выраженных в миллисекундах [1], и я хочу знать, какие события находятся внутри текущей недели и текущего месяца, но я не могу понять, как получить первый день (день/месяц/год) текущей недели и преобразовать его в миллисекунды, то же самое в течение первого дня месяца.
[1]Since January 1, 1970, 00:00:00 GMT
Ответы
Ответ 1
На этой неделе в миллисекундах:
// get today and clear time of day
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0); // ! clear would not reset the hour of day !
cal.clear(Calendar.MINUTE);
cal.clear(Calendar.SECOND);
cal.clear(Calendar.MILLISECOND);
// get start of this week in milliseconds
cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
System.out.println("Start of this week: " + cal.getTime());
System.out.println("... in milliseconds: " + cal.getTimeInMillis());
// start of the next week
cal.add(Calendar.WEEK_OF_YEAR, 1);
System.out.println("Start of the next week: " + cal.getTime());
System.out.println("... in milliseconds: " + cal.getTimeInMillis());
Этот месяц в миллисекундах:
// get today and clear time of day
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0); // ! clear would not reset the hour of day !
cal.clear(Calendar.MINUTE);
cal.clear(Calendar.SECOND);
cal.clear(Calendar.MILLISECOND);
// get start of the month
cal.set(Calendar.DAY_OF_MONTH, 1);
System.out.println("Start of the month: " + cal.getTime());
System.out.println("... in milliseconds: " + cal.getTimeInMillis());
// get start of the next month
cal.add(Calendar.MONTH, 1);
System.out.println("Start of the next month: " + cal.getTime());
System.out.println("... in milliseconds: " + cal.getTimeInMillis());
Ответ 2
Первый день недели можно определить с помощью java.util.Calendar
следующим образом:
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.setTimeInMillis(timestamp);
while (calendar.get(Calendar.DAY_OF_WEEK) > calendar.getFirstDayOfWeek()) {
calendar.add(Calendar.DATE, -1); // Substract 1 day until first day of week.
}
long firstDayOfWeekTimestamp = calendar.getTimeInMillis();
Первый день месяца можно определить следующим образом:
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.setTimeInMillis(timestamp);
while (calendar.get(Calendar.DATE) > 1) {
calendar.add(Calendar.DATE, -1); // Substract 1 day until first day of month.
}
long firstDayOfMonthTimestamp = calendar.getTimeInMillis();
Довольно подробный, да.
Java 7 будет поставляться с значительно улучшенными API дат и времени (JSR-310). Если вы еще не можете переключиться, вы можете использовать JodaTime, что делает его все менее сложным:
DateTime dateTime = new DateTime(timestamp);
long firstDayOfWeekTimestamp = dateTime.withDayOfWeek(1).getMillis();
и
DateTime dateTime = new DateTime(timestamp);
long firstDayOfMonthTimestamp = dateTime.withDayOfMonth(1).getMillis();
Ответ 3
java.time
Среда java.time в Java 8 и более поздних версиях заменяет старые классы java.util.Date/.Calendar. Старые классы оказались проблематичными, запутанными и ошибочными. Избежать их.
Инфраструктура java.time основана на очень успешной библиотеке Joda-Time, определенной в JSR 310, расширенной проектом ThreeTen-Extra и объясненной в Учебном пособии.
Instant
Класс Instant
представляет момент на временной шкале в UTC.
Фреймворк java.time имеет разрешение наносекунд или 9 цифр доли секунды. Миллисекунды - это всего лишь 3 цифры доли секунды. Поскольку разрешение в миллисекундах является обычным, java.time включает удобный заводской метод.
long millisecondsSinceEpoch = 1446959825213L;
Instant instant = Instant.ofEpochMilli ( millisecondsSinceEpoch );
миллисекундыС начала эпохи: 1446959825213 мгновенно: 2015-11-08T05: 17: 05.213Z
ZonedDateTime
Чтобы учесть текущую неделю и текущий месяц, нам нужно применить определенный часовой пояс.
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant , zoneId );
В zoneId: Америка/Монреаль: 2015-11-08T00: 17: 05.213-05: 00 [Америка/Монреаль]
Полуоткрытый
В работе с датой и временем мы обычно используем подход Half-Open для определения промежутка времени. Начало включительно, а окончание - эксклюзив. Вместо того, чтобы пытаться определить последнюю долю секунды в конце недели (или месяца), мы получаем первый момент следующей недели (или месяца). Таким образом, неделя начинается с первого момента понедельника и продолжается, но не включает первый момент следующего понедельника.
Пусть первый день недели и последний. Среда java.time включает в себя инструмент для этого, метод with
и перечисление ChronoField
.
По умолчанию java.time использует стандарт ISO 8601. Таким образом, понедельник - первый день недели (1), а воскресенье - последнее (7).
ZonedDateTime firstOfWeek = zdt.with ( ChronoField.DAY_OF_WEEK , 1 ); // ISO 8601, Monday is first day of week.
ZonedDateTime firstOfNextWeek = firstOfWeek.plusWeeks ( 1 );
Эта неделя начинается с: 2015-11-02T00: 17: 05.213-05: 00 [Америка/Монреаль] до 2015-11-09T00: 17: 05.213-05: 00 [Америка/Монреаль]
К сожалению! Посмотрите на время суток на эти значения. Мы хотим первый момент дня. Первый момент дня не всегда 00:00:00.000
из-за 00:00:00.000
на летнее время (DST) или других аномалий. Поэтому мы должны позволить java.time внести коррективы от нашего имени. Чтобы сделать это, мы должны пройти через класс LocalDate
.
ZonedDateTime firstOfWeek = zdt.with ( ChronoField.DAY_OF_WEEK , 1 ); // ISO 8601, Monday is first day of week.
firstOfWeek = firstOfWeek.toLocalDate ().atStartOfDay ( zoneId );
ZonedDateTime firstOfNextWeek = firstOfWeek.plusWeeks ( 1 );
Эта неделя начинается с: 2015-11-02T00: 00-05: 00 [Америка/Монреаль] до 2015-11-09T00: 00-05: 00 [Америка/Монреаль]
И то же самое за месяц.
ZonedDateTime firstOfMonth = zdt.with ( ChronoField.DAY_OF_MONTH , 1 );
firstOfMonth = firstOfMonth.toLocalDate ().atStartOfDay ( zoneId );
ZonedDateTime firstOfNextMonth = firstOfMonth.plusMonths ( 1 );
Этот месяц начинается с: 2015-11-01T00: 00-04: 00 [Америка/Монреаль] до 2015-12-01T00: 00-05: 00 [Америка/Монреаль]
YearMonth
Еще один способ узнать, есть ли пара моментов в одном месяце, - это проверить одно и то же значение YearMonth
.
Например, предположим, что thisZdt
и thatZdt
являются объектами ZonedDateTime
:
boolean inSameMonth = YearMonth.from( thisZdt ).equals( YearMonth.from( thatZdt ) ) ;
миллисекунды
Я настоятельно рекомендую не делать вашу работу с датой и временем в миллисекундах от эпохи. Это действительно способ, которым классы даты и времени работают внутренне, но у нас есть причины по причине. Обработка отсчетов из эпохи неуклюжа, так как значения не понятны людям, поэтому отладка и ведение журнала трудны и подвержены ошибкам. И, как мы уже видели, могут быть разные разрешения; старые классы Java и библиотека Joda-Time используют миллисекунды, в то время как базы данных, такие как Postgres, используют микросекунды, а теперь java.time использует наносекунды.
Будете ли вы обрабатывать текст как биты, или вы позволите классам, таким как String
, StringBuffer
и StringBuilder
обрабатывать такие детали?
Но если вы настаиваете, из ZonedDateTime
получите Instant
, и из этого получите миллисекундный отсчет от эпохи. Но имейте в виду, что этот вызов может означать потерю данных. Любые микросекунды или наносекунды, которые могут быть в вашем ZonedDateTime
/Instant
будут усечены (потеряны).
long millis = firstOfWeek.toInstant().toEpochMilli(); // Possible data loss.
О java.time
Инфраструктура java.time встроена в Java 8 и более поздние версии. Эти классы вытеснять неприятные старые устаревшие классы даты и времени, такие как java.util.Date
, Calendar
, и SimpleDateFormat
.
Чтобы узнать больше, смотрите Oracle Tutorial. И поиск для многих примеров и объяснений. Спецификация JSR 310.
Проект Joda-Time, находящийся сейчас в режиме обслуживания, рекомендует перейти на классы java.time.
Вы можете обмениваться объектами java.time напрямую с вашей базой данных. Используйте драйвер JDBC, соответствующий JDBC 4.2 или более поздней версии. Нет необходимости в строках, нет необходимости в java.sql.*
.
Где взять классы java.time?
Ответ 4
Внимание!
while (calendar.get(Calendar.DAY_OF_WEEK) > calendar.getFirstDayOfWeek()) {
calendar.add(Calendar.DATE, -1); // Substract 1 day until first day of week.
}
- хорошая идея, но есть некоторые проблемы:
Например, я из Украины и calendar.getFirstDayOfWeek() в моей стране - 2 (понедельник).
И сегодня 1 (воскресенье). В этом случае calendar.add не вызывается.
Итак, правильный способ - это изменить " > " на "! =":
while (calendar.get(Calendar.DAY_OF_WEEK) != calendar.getFirstDayOfWeek()) {...
Ответ 5
Чтобы получить первый день месяца, просто получите Date
и установите текущий день на день 1 месяца. Очищайте часы, минуты, секунды и миллисекунды, если вам это нужно.
private static Date firstDayOfMonth(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.DATE, 1);
return calendar.getTime();
}
Первый день недели - это одно и то же, но вместо этого Calendar.DAY_OF_WEEK
private static Date firstDayOfWeek(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.DAY_OF_WEEK, 1);
return calendar.getTime();
}
Ответ 6
Я создал несколько методов для этого:
public static String catchLastDayOfCurrentWeek(String pattern) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.clear(Calendar.MINUTE);
cal.clear(Calendar.SECOND);
cal.clear(Calendar.MILLISECOND);
cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
return calendarToString(cal, pattern);
}
public static String catchLastDayOfCurrentWeek(String pattern) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.clear(Calendar.MINUTE);
cal.clear(Calendar.SECOND);
cal.clear(Calendar.MILLISECOND);
cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
cal.add(Calendar.WEEK_OF_YEAR, 1);
cal.add(Calendar.MILLISECOND, -1);
return calendarToString(cal, pattern);
}
public static String catchTheFirstDayOfThemonth(Integer month, pattern padrao) {
Calendar cal = GregorianCalendar.getInstance();
cal.setTime(new Date());
cal.set(Calendar.MONTH, month);
cal.set(Calendar.DAY_OF_MONTH, 1);
return calendarToString(cal, pattern);
}
public static String catchTheLastDayOfThemonth(Integer month, String pattern) {
Calendar cal = GregorianCalendar.getInstance();
cal.setTime(new Date());
cal.set(cal.get(Calendar.YEAR), month, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
return calendarToString(cal, pattern);
}
public static String calendarToString(Calendar calendar, String pattern) {
if (calendar == null) {
return "";
}
SimpleDateFormat format = new SimpleDateFormat(pattern, LocaleUtils.DEFAULT_LOCALE);
return format.format(calendar.getTime());
}
Здесь вы можете увидеть .
Ответ 7
В этом случае:
// get today and clear time of day
Calendar cal = Calendar.getInstance();
cal.clear(Calendar.HOUR_OF_DAY); <---- is the current hour not 0 hour
cal.clear(Calendar.MINUTE);
cal.clear(Calendar.SECOND);
cal.clear(Calendar.MILLISECOND);
Итак, Calendar.HOUR_OF_DAY возвращает 8, 9, 12, 15, 18 как текущий текущий час.
Я думаю, будет лучше изменить такую строку:
c.set(Calendar.HOUR_OF_DAY,0);
таким образом, день всегда начинается с 0 часов
Ответ 8
Получить первое число следующего месяца: -
SimpleDateFormat df = new SimpleDateFormat("MM-dd-yyyy");
String selectedDate="MM-dd-yyyy like 07-02-2018";
Date dt = df.parse(selectedDate);'enter code here'
calendar = Calendar.getInstance();
calendar.setTime(dt);
calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH) + 1);
String firstDate = df.format(calendar.getTime());
System.out.println("firstDateof next month ==>" + firstDate);
Ответ 9
Вы должны иметь возможность конвертировать свой номер в Java-календарь, например:
Calendar.getInstance().setTimeInMillis(myDate);
Оттуда сравнение не должно быть слишком сложным.
Ответ 10
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Scanner;
/**
This Program will display day for, 1st and last days in a given month and year
@author Manoj Kumar Dunna
Mail Id : [email protected]
*/
public class DayOfWeek {
public static void main(String[] args) {
String strDate = null;
int year = 0, month = 0;
Scanner sc = new Scanner(System.in);
System.out.print("Enter YYYY/MM: ");
strDate = sc.next();
Calendar cal = new GregorianCalendar();
String [] date = strDate.split("/");
year = Integer.parseInt(date[0]);
month = Integer.parseInt(date[1]);
cal.set(year, month-1, 1);
System.out.println(new SimpleDateFormat("EEEE").format(cal.getTime()));
cal.add(Calendar.MONTH, 1);
cal.add(Calendar.DAY_OF_YEAR, -1);
System.out.println(new SimpleDateFormat("EEEE").format(cal.getTime()));
}
}
Ответ 11
Simple Solution:
package com.util.calendarutil;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
public class CalUtil {
public static void main(String args[]){
DateFormat df = new SimpleDateFormat("dd/mm/yyyy");
Date dt = null;
try {
dt = df.parse("23/01/2016");
} catch (ParseException e) {
System.out.println("Error");
}
Calendar cal = Calendar.getInstance();
cal.setTime(dt);
cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
Date startDate = cal.getTime();
cal.add(Calendar.DATE, 6);
Date endDate = cal.getTime();
System.out.println("Start Date:"+startDate+"End Date:"+endDate);
}
}
Ответ 12
я использую этот трюк, чтобы получить первый день текущего месяца, обратите внимание, что порядок 1 для воскресенья 2 для понедельника 3 для вторника.... и так далее
Calendar cal = new GregorianCalendar();
int startDay = cal.get(Calendar.DAY_OF_YEAR) % 7 + 1;
System.out.println(startDay);
Ответ 13
public static void main(String[] args) {
System.out.println(getMonthlyEpochList(1498867199L,12,"Monthly"));
}
public static Map<String,String> getMonthlyEpochList(Long currentEpoch, int noOfTerms, String timeMode) {
Map<String,String> map = new LinkedHashMap<String,String>();
int month = 0;
while(noOfTerms != 0) {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MONTH, month);
calendar.set(Calendar.DATE, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
Date monthFirstDay = calendar.getTime();
calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
Date monthLastDay = calendar.getTime();
map.put(getMMYY(monthFirstDay.getTime()), monthFirstDay + ":" +monthLastDay);
month--;
noOfTerms--;
}
return map;
}