Java 如何获取当前周和月的第一天?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2937086/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 14:38:40  来源:igfitidea点击:

How to get the first day of the current week and month?

javaandroiddate

提问by cesarlinux

I have the date of several events expressed in milliseconds[1], and I want to know which events are inside the current week and the current month, but I can't figure out how to obtain the first day (day/month/year) of the running week and convert it to milliseconds, the same for the first day of the month.

我有几个事件的日期以毫秒[1]表示,我想知道哪些事件在当前周和当月内,但我不知道如何获得第一天(日/月/年) ) 并将其转换为毫秒,与该月的第一天相同。

[1]Since January 1, 1970, 00:00:00 GMT

采纳答案by COME FROM

This week in milliseconds:

本周以毫秒为单位:

// 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());

This month in milliseconds:

本月以毫秒为单位:

// 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());

回答by ig0774

You should be able to convert your number to a Java Calendar, e.g.:

您应该能够将您的号码转换为 Java 日历,例如:

 Calendar.getInstance().setTimeInMillis(myDate);

From there, the comparison shouldn't be too hard.

从那里,比较不应该太难。

回答by BalusC

The first day of week can be determined with help of java.util.Calendaras follows:

可以通过以下方式确定一周的第一天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();

The first day of month can be determined as follows:

一个月的第一天可以确定如下:

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();

Pretty verbose, yes.

很冗长,是的。



Java 7 will come with a much improved Date and Time API (JSR-310). If you can't switch yet, then you can as far use JodaTimewhich makes it all less complicated:

Java 7 将带有一个大大改进的日期和时间 API ( JSR-310)。如果您还不能切换,那么您可以使用JodaTime,这使它变得不那么复杂:

DateTime dateTime = new DateTime(timestamp);
long firstDayOfWeekTimestamp = dateTime.withDayOfWeek(1).getMillis();

and

DateTime dateTime = new DateTime(timestamp);
long firstDayOfMonthTimestamp = dateTime.withDayOfMonth(1).getMillis();

回答by cesarlinux

In this case:

在这种情况下:

// 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);

So the Calendar.HOUR_OF_DAY returns 8, 9, 12, 15, 18 as the current running hour. I think will be better change such line by:

所以 Calendar.HOUR_OF_DAY 返回 8, 9, 12, 15, 18 作为当前运行小时。我认为通过以下方式更好地改变这样的行:

c.set(Calendar.HOUR_OF_DAY,0);

this way the day always begin at 0 hour

这样一天总是从 0 小时开始

回答by Diego Pino

To get the first day of the month, simply get a Dateand set the current day to day 1 of the month. Clear hour, minute, second and milliseconds if you need it.

要获取该月的第一天,只需获取 aDate并将当前日期设置为该月的第 1 天。如果需要,清除小时、分钟、秒和毫秒。

private static Date firstDayOfMonth(Date date) {
   Calendar calendar = Calendar.getInstance();
   calendar.setTime(date);
   calendar.set(Calendar.DATE, 1);
   return calendar.getTime();
}

First day of the week is the same thing, but using Calendar.DAY_OF_WEEKinstead

一周的第一天是同样的事情,但使用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();
}

回答by alcsan

Attention!

注意力!

while (calendar.get(Calendar.DAY_OF_WEEK) > calendar.getFirstDayOfWeek()) {
    calendar.add(Calendar.DATE, -1); // Substract 1 day until first day of week.
}

is good idea, but there is some issue: For example, i'm from Ukraine and calendar.getFirstDayOfWeek() in my country is 2 (Monday). And today is 1 (Sunday). In this case calendar.add not called.

是个好主意,但有一些问题:例如,我来自乌克兰,我的国家/地区的 calendar.getFirstDayOfWeek() 是 2(星期一)。而今天是 1(星期日)。在这种情况下,没有调用 calendar.add。

So, correct way is change ">" to "!=":

因此,正确的方法是将“>”更改为“!=”:

while (calendar.get(Calendar.DAY_OF_WEEK) != calendar.getFirstDayOfWeek()) {...

回答by Manoj Kumar

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()));
    }
}

回答by Basil Bourque

java.time

时间

The java.timeframework in Java 8 and later supplants the old java.util.Date/.Calendar classes. The old classes have proven to be troublesome, confusing, and flawed. Avoid them.

Java 8 及更高版本中的java.time框架取代了旧的 java.util.Date/.Calendar 类。旧的类已被证明是麻烦、混乱和有缺陷的。避开它们。

The java.time framework is inspired by the highly-successful Joda-Timelibrary, defined by JSR?310, extended by the ThreeTen-Extraproject, and explained in the Tutorial.

java.time 框架的灵感来自非常成功的Joda-Time库,该库由JSR?310定义,由ThreeTen-Extra项目扩展,并在教程中进行了解释。

Instant

Instant

The Instantclass represents a moment on the timeline in UTC.

Instant类代表在时间轴上一个时刻UTC

The java.time framework has a resolution of nanoseconds, or 9 digits of a fractional second. Milliseconds is only 3 digits of a fractional second. Because millisecond resolutionis common, java.time includes a handy factory method.

java.time 框架的分辨率为纳秒,或小数秒的 9 位数字。毫秒只是小数秒的 3 位数字。因为毫秒分辨率很常见,所以 java.time 包含一个方便的工厂方法。

long millisecondsSinceEpoch = 1446959825213L;
Instant instant = Instant.ofEpochMilli ( millisecondsSinceEpoch );

millisecondsSinceEpoch: 1446959825213 is instant: 2015-11-08T05:17:05.213Z

毫秒自纪元:1446959825213 是即时的:2015-11-08T05:17:05.213Z

ZonedDateTime

ZonedDateTime

To consider current week and current month, we need to apply a particular time zone.

要考虑当前周和当前月,我们需要应用特定的时区。

ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant , zoneId );

In zoneId: America/Montreal that is: 2015-11-08T00:17:05.213-05:00[America/Montreal]

在 zoneId: America/Montreal 即:2015-11-08T00:17:05.213-05:00[America/Montreal]

Half-Open

半开

In date-time work, we commonly use the Half-Open approach to defining a span of time. The beginning is inclusivewhile the ending in exclusive. Rather than try to determine the last split-second of the end of the week (or month), we get the first moment of the followingweek (or month). So a week runs from the first moment of Monday and goes up to but not includingthe first moment of the followingMonday.

在日期时间工作中,我们通常使用半开放方法来定义时间跨度。开头是包容的,而结尾是独占的。我们不是尝试确定一周(或一个月)结束的最后一秒,而是获得一周(或一个月)的第一个时刻。所以一个星期从周一的第一时刻运行,并上升到但不包括在第一时刻以下星期一

Let's the first day of the week, and last. The java.time framework includes a tool for that, the withmethod and the ChronoFieldenum.

让我们一周的第一天,也是最后一天。java.time 框架包括一个工具,with方法和ChronoField枚举。

By default, java.time uses the ISO 8601standard. So Monday is the first day of the week (1) and Sunday is last (7).

默认情况下,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 );

That week runs from: 2015-11-02T00:17:05.213-05:00[America/Montreal] to 2015-11-09T00:17:05.213-05:00[America/Montreal]

那一周从:2015-11-02T00:17:05.213-05:00[America/Montreal] 到 2015-11-09T00:17:05.213-05:00[America/Montreal]

Oops! Look at the time-of-day on those values. We want the first moment of the day. The first moment of the day is not always 00:00:00.000because of Daylight Saving Time (DST) or other anomalies. So we should let java.time make the adjustment on our behalf. To do that, we must go through the LocalDateclass.

哎呀!查看这些值的时间。我们想要一天中的第一刻。一天中的第一个时刻并不总是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 );

That week runs from: 2015-11-02T00:00-05:00[America/Montreal] to 2015-11-09T00:00-05:00[America/Montreal]

那一周从:2015-11-02T00:00-05:00[America/Montreal] 到 2015-11-09T00:00-05:00[America/Montreal]

And same for the month.

这个月也一样。

ZonedDateTime firstOfMonth = zdt.with ( ChronoField.DAY_OF_MONTH , 1 );
firstOfMonth = firstOfMonth.toLocalDate ().atStartOfDay ( zoneId );
ZonedDateTime firstOfNextMonth = firstOfMonth.plusMonths ( 1 );

That month runs from: 2015-11-01T00:00-04:00[America/Montreal] to 2015-12-01T00:00-05:00[America/Montreal]

该月从:2015-11-01T00:00-04:00[America/Montreal] 到 2015-12-01T00:00-05:00[America/Montreal]

YearMonth

YearMonth

Another way to see if a pair of moments are in the same month is to check for the same YearMonthvalue.

查看一对时刻是否在同一月份的另一种方法是检查相同的YearMonth值。

For example, assuming thisZdtand thatZdtare both ZonedDateTimeobjects:

例如,假设thisZdtthatZdt都是ZonedDateTime对象:

boolean inSameMonth = YearMonth.from( thisZdt ).equals( YearMonth.from( thatZdt ) ) ;

Milliseconds

毫秒

I strongly recommend against doing your date-time work in milliseconds-from-epoch. That is indeed the way date-time classes tend to work internally, but we have the classes for a reason. Handling a count-from-epoch is clumsy as the values are not intelligible by humans so debugging and logging is difficult and error-prone. And, as we've already seen, different resolutions may be in play; old Java classes and Joda-Time library use milliseconds, while databases like Postgres use microseconds, and now java.time uses nanoseconds.

我强烈建议不要以毫秒为单位进行日期时间工作。这确实是日期时间类在内部工作的方式,但我们有这些类是有原因的。处理从纪元开始的计数很笨拙,因为人类无法理解这些值,因此调试和记录很困难且容易出错。而且,正如我们已经看到的,不同的分辨率可能在起作用;旧的 Java 类和 Joda-Time 库使用毫秒,而像 Postgres 这样的数据库使用微秒,而现在 java.time 使用纳秒。

Would you handle text as bits, or do you let classes such as String, StringBuffer, and StringBuilderhandle such details?

你会处理文本作为位,还是你让类,如StringStringBufferStringBuilder处理这样的细节?

But if you insist, from a ZonedDateTimeget an Instant, and from that get a milliseconds-count-from-epoch. But keep in mind this call can mean loss of data. Any microseconds or nanoseconds that you might have in your ZonedDateTime/Instantwill be truncated (lost).

但是如果你坚持,从一个ZonedDateTimeget an Instant,然后从那个得到一个毫秒计数从纪元。但请记住,此调用可能意味着数据丢失。您ZonedDateTime/ 中可能存在的任何微秒或纳秒都Instant将被截断(丢失)。

long millis = firstOfWeek.toInstant().toEpochMilli();  // Possible data loss.


About java.time

关于java.time

The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310

The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.

现在处于维护模式Joda-Time项目建议迁移到java.time类。

You may exchange java.timeobjects directly with your database. Use a JDBC drivercompliant with JDBC 4.2or later. No need for strings, no need for java.sql.*classes.

您可以直接与您的数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC 驱动程序。不需要字符串,不需要类。java.sql.*

Where to obtain the java.time classes?

从哪里获得 java.time 类?

回答by Varun

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);


    }

}

回答by Alberto Cerqueira

I have created some methods for this:

我为此创建了一些方法:

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());
}

You can see more here.

你可以在这里看到更多。