[英]How to get the first day of the current week and month?
我有几个事件的日期以毫秒[1] 表示,我想知道当前周和当前月份内有哪些事件,但我不知道如何获取第一天(日/月/年) 并将其转换为毫秒,与该月的第一天相同。
[1]Since January 1, 1970, 00:00:00 GMT
本周以毫秒为单位:
// 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());
可以在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();
Java 8 及更高版本中的java.time框架取代了旧的 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: America/Montreal 即:2015-11-08T00:17:05.213-05:00[America/Montreal]
在日期时间工作中,我们通常使用半开放方法来定义时间跨度。 开头是包容的,而结尾是独占的。 我们不是尝试确定一周(或一个月)结束的最后一秒,而是获得下一周(或一个月)的第一个时刻。 所以一个星期从周一的第一时刻运行,上升,但不包括在下周一的第一刻。
让我们一周的第一天,也是最后一天。 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[America/Montreal] 到 2015-11-09T00:17:05.213-05:00[America/Montreal]
哎呀! 查看这些值的时间。 我们想要一天中的第一刻。 由于夏令时 (DST) 或其他异常情况,一天的第一时刻并不总是00:00:00.000
。 所以我们应该让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[America/Montreal] 到 2015-11-09T00:00-05:00[America/Montreal]
这个月也一样。
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[America/Montreal] 到 2015-12-01T00:00-05:00[America/Montreal]
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 8 及更高版本中。 这些类取代麻烦的老传统日期时间类,如java.util.Date
, Calendar
,和SimpleDateFormat
。
要了解更多信息,请参阅Oracle 教程。 并在 Stack Overflow 上搜索许多示例和解释。 规范是JSR 310 。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
您可以直接与您的数据库交换java.time对象。 使用符合JDBC 4.2或更高版本的JDBC 驱动程序。 不需要字符串,不需要java.sql.*
类。
从哪里获得 java.time 类?
注意力!
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()) {...
您可以使用java.time
包(自 Java8 和后期)获取日/周/月的开始/结束。
下面的 util 类示例:
import org.junit.Test;
import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
public class DateUtil {
private static final ZoneId DEFAULT_ZONE_ID = ZoneId.of("UTC");
public static LocalDateTime startOfDay() {
return LocalDateTime.now(DEFAULT_ZONE_ID).with(LocalTime.MIN);
}
public static LocalDateTime endOfDay() {
return LocalDateTime.now(DEFAULT_ZONE_ID).with(LocalTime.MAX);
}
public static boolean belongsToCurrentDay(final LocalDateTime localDateTime) {
return localDateTime.isAfter(startOfDay()) && localDateTime.isBefore(endOfDay());
}
//note that week starts with Monday
public static LocalDateTime startOfWeek() {
return LocalDateTime.now(DEFAULT_ZONE_ID)
.with(LocalTime.MIN)
.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
}
//note that week ends with Sunday
public static LocalDateTime endOfWeek() {
return LocalDateTime.now(DEFAULT_ZONE_ID)
.with(LocalTime.MAX)
.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
}
public static boolean belongsToCurrentWeek(final LocalDateTime localDateTime) {
return localDateTime.isAfter(startOfWeek()) && localDateTime.isBefore(endOfWeek());
}
public static LocalDateTime startOfMonth() {
return LocalDateTime.now(DEFAULT_ZONE_ID)
.with(LocalTime.MIN)
.with(TemporalAdjusters.firstDayOfMonth());
}
public static LocalDateTime endOfMonth() {
return LocalDateTime.now(DEFAULT_ZONE_ID)
.with(LocalTime.MAX)
.with(TemporalAdjusters.lastDayOfMonth());
}
public static boolean belongsToCurrentMonth(final LocalDateTime localDateTime) {
return localDateTime.isAfter(startOfMonth()) && localDateTime.isBefore(endOfMonth());
}
public static long toMills(final LocalDateTime localDateTime) {
return localDateTime.atZone(DEFAULT_ZONE_ID).toInstant().toEpochMilli();
}
public static Date toDate(final LocalDateTime localDateTime) {
return Date.from(localDateTime.atZone(DEFAULT_ZONE_ID).toInstant());
}
public static String toString(final LocalDateTime localDateTime) {
return localDateTime.format(DateTimeFormatter.ISO_DATE_TIME);
}
@Test
public void test() {
//day
final LocalDateTime now = LocalDateTime.now();
System.out.println("Now: " + toString(now) + ", in mills: " + toMills(now));
System.out.println("Start of day: " + toString(startOfDay()));
System.out.println("End of day: " + toString(endOfDay()));
System.out.println("Does '" + toString(now) + "' belong to the current day? > " + belongsToCurrentDay(now));
final LocalDateTime yesterday = now.minusDays(1);
System.out.println("Does '" + toString(yesterday) + "' belong to the current day? > " + belongsToCurrentDay(yesterday));
final LocalDateTime tomorrow = now.plusDays(1);
System.out.println("Does '" + toString(tomorrow) + "' belong to the current day? > " + belongsToCurrentDay(tomorrow));
//week
System.out.println("Start of week: " + toString(startOfWeek()));
System.out.println("End of week: " + toString(endOfWeek()));
System.out.println("Does '" + toString(now) + "' belong to the current week? > " + belongsToCurrentWeek(now));
final LocalDateTime previousWeek = now.minusWeeks(1);
System.out.println("Does '" + toString(previousWeek) + "' belong to the current week? > " + belongsToCurrentWeek(previousWeek));
final LocalDateTime nextWeek = now.plusWeeks(1);
System.out.println("Does '" + toString(nextWeek) + "' belong to the current week? > " + belongsToCurrentWeek(nextWeek));
//month
System.out.println("Start of month: " + toString(startOfMonth()));
System.out.println("End of month: " + toString(endOfMonth()));
System.out.println("Does '" + toString(now) + "' belong to the current month? > " + belongsToCurrentMonth(now));
final LocalDateTime previousMonth = now.minusMonths(1);
System.out.println("Does '" + toString(previousMonth) + "' belong to the current month? > " + belongsToCurrentMonth(previousMonth));
final LocalDateTime nextMonth = now.plusMonths(1);
System.out.println("Does '" + toString(nextMonth) + "' belong to the current month? > " + belongsToCurrentMonth(nextMonth));
}
}
测试输出:
Now: 2020-02-16T22:12:49.957, in mills: 1581891169957
Start of day: 2020-02-16T00:00:00
End of day: 2020-02-16T23:59:59.999999999
Does '2020-02-16T22:12:49.957' belong to the current day? > true
Does '2020-02-15T22:12:49.957' belong to the current day? > false
Does '2020-02-17T22:12:49.957' belong to the current day? > false
Start of week: 2020-02-10T00:00:00
End of week: 2020-02-16T23:59:59.999999999
Does '2020-02-16T22:12:49.957' belong to the current week? > true
Does '2020-02-09T22:12:49.957' belong to the current week? > false
Does '2020-02-23T22:12:49.957' belong to the current week? > false
Start of month: 2020-02-01T00:00:00
End of month: 2020-02-29T23:59:59.999999999
Does '2020-02-16T22:12:49.957' belong to the current month? > true
Does '2020-01-16T22:12:49.957' belong to the current month? > false
Does '2020-03-16T22:12:49.957' belong to the current month? > false
要获取该月的第一天,只需获取一个Date
并将当前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();
}
我为此创建了一些方法:
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());
}
你可以在这里看到更多。
在这种情况下:
// 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 小时开始
获取下个月的第一个日期:-
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);
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 : manojdunna@gmail.com
*/
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()));
}
}
您应该能够将您的号码转换为 Java 日历,例如:
Calendar.getInstance().setTimeInMillis(myDate);
从那里,比较不应该太难。
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);
}
}
在Java 中
LocalDateTime firstOfWeek = LocalDateTime.now().with(ChronoField.DAY_OF_WEEK, 1).toLocalDate().atStartOfDay(); // 2020-06-08 00:00 MONDAY
LocalDateTime firstOfMonth = LocalDateTime.now().with(ChronoField.DAY_OF_MONTH , 1).toLocalDate().atStartOfDay(); // 2020-06-01 00:00
// Convert to milliseconds:
firstOfWeek.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
在科特林
val firstOfWeek = LocalDateTime.now().with(ChronoField.DAY_OF_WEEK, 1).toLocalDate().atStartOfDay() // 2020-06-08 00:00 MONDAY
val firstOfMonth = LocalDateTime.now().with(ChronoField.DAY_OF_MONTH , 1).toLocalDate().atStartOfDay() // 2020-06-01 00:00
// Convert to milliseconds:
firstOfWeek.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()
我用这个技巧来获得当月的第一天注意顺序是星期日 1 星期二星期一 3 星期二......等等
Calendar cal = new GregorianCalendar();
int startDay = cal.get(Calendar.DAY_OF_YEAR) % 7 + 1;
System.out.println(startDay);
这是使用Calendar
获取所选日期的第一天和最后一天的好方法:
private fun getFirstDayOfWeek(date: Date): Date {
val calendar = Calendar.getInstance()
calendar.time = date
calendar[Calendar.DAY_OF_WEEK] = calendar.firstDayOfWeek
return calendar.time
}
private fun getLastDayOfWeek(date: Date): Date {
val calendar = Calendar.getInstance()
calendar.time = date
calendar[Calendar.DAY_OF_WEEK] = calendar.firstDayOfWeek
calendar.add(Calendar.DATE, 6)
return calendar.time
}
只需要将选定的日期传递给上述函数。
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.