【问题标题】:Get Date based on day count in Java根据Java中的天数获取日期
【发布时间】:2013-04-26 03:11:13
【问题描述】:

简单的问题,但令人惊讶的是,谷歌对此几乎没有。我有今年 1 月 1 日的number of days。如何在 Java 中将其转换为 date

【问题讨论】:

    标签: java date calendar


    【解决方案1】:

    tl;博士

    Year.of( 2017 )
        .atDay( 159 )
    

    2017-06-08

    …或当前年份…

    Year.now( ZoneId.of( "America/Montreal" ) )
        .atDay( 159 )
    

    2018-06-08

    换个方向,从日期到一年中的某一天。

    LocalDate.now( ZoneId.of( "America/Montreal" )
             .getDayOfYear()
    

    159

    使用 java.time

    处理日期时间的现代方法是使用 java.time 类。麻烦的旧日期时间包。麻烦的旧日期时间类,例如 java.util.Datejava.util.Calendarjava.text.SimpleTextFormat,现在是 legacy,被 java.time 类所取代。

    Year 类显然代表一年。要获取当前年份,我们需要当前日期。

    时区对于确定日期和年份至关重要。对于任何给定的时刻,日期在全球范围内因区域而异。例如,Paris France 中午夜后几分钟是新的一天,而 Montréal Québec 中仍然是“昨天”。同样,元旦在巴黎午夜过后几分钟是新的一年,而在魁北克仍然是“去年”。

    continent/region 的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用 3-4 个字母的缩写,例如 ESTIST,因为它们不是真正的时区,没有标准化,甚至不是唯一的 (!)。

    ZoneId z = ZoneId.of( "America/Montreal" );
    Year year = Year.now( z );
    

    如果您有特定的年份,请传递年份编号。

    Year year = Year.of( 2017 );
    

    Year 类包含一个方法 atDay,用于在传递 Leap Year 中从 1 到 365 或 366 的年份数字时生成 LocalDateLocalDate 类表示没有时间和时区的仅日期值。

    LocalDate localDate = year.atDay( 159 );
    

    反过来,您可以致电LocalDate::getDayOfYear 询问LocalDate 的日期。

    int dayOfYear = localDate.getDayOfYear() ;
    

    关于java.time

    java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

    Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

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

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

    从哪里获得 java.time 类?

    ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

    【讨论】:

      【解决方案2】:

      使用日历进行日期运算

          Calendar c = Calendar.getInstance();
          c.set(Calendar.YEAR, 2013);
          c.set(Calendar.MONTH, Calendar.JANUARY);
          c.set(Calendar.DATE, 1);
          c.set(Calendar.HOUR, 0);
          c.set(Calendar.MINUTE, 0);
          c.set(Calendar.SECOND, 0);
          c.set(Calendar.MILLISECOND, 0);
          c.add(Calendar.DATE, numberOfDays);
          Date date = c.getTime();
      

      请注意,由于 DST(夏令时),不同地区的结果可能会有所不同。上面的示例使用默认语言环境。

      【讨论】:

      【解决方案3】:

      我发现JodaTime 在日期处理方面使用起来非常优雅。有了它,你可以这样做:

      DateTime date = new DateTime().withDayOfYear(dayOfYear);
      

      【讨论】:

        【解决方案4】:

        您可以简单地使用SimpleDateFormatString 转换为Date。模式D可以用来表示一年中的天数。

        前提是你有

        int numberOfDays = 42; // Arbitrary number.
        

        那么这个计算自 1970 年 1 月 1 日以来的天数 (the Epoch)

        Date date = new SimpleDateFormat("D").parse(String.valueOf(numberOfDays));
        

        或者,这个计算自当年 1 月 1 日以来的天数。

        Date date = new SimpleDateFormat("D yyyy").parse(numberOfDays + " " + Calendar.getInstance().get(Calendar.YEAR));
        

        【讨论】:

        • 我喜欢这个。有没有办法我也可以添加从午夜开始的分钟数?
        【解决方案5】:

        如果您是 Android 开发人员并使用 JodaTime,这就是您在 java 8 中获得等价物的方式。

        LocalDate.ofYearDay("2020", 255).getDayOfWeek().getValue()
        

        使用这个是因为 ofYearDay 仅在 Android >= 26 以上才支持;

        MutableDateTime mutableDateTime1 = new MutableDateTime();
        mutableDateTime1.setYear("2020");
        mutableDateTime1.setDayOfYear(255);
        LocalDate.fromDateFields(mutableDateTime1.toDate()).getDayOfWeek();
        

        【讨论】:

        【解决方案6】:

        使用GregorianCalendarsimpleDateFormat

        int days = 20;
        GregorianCalendar dayCountofYear = new GregorianCalendar(2020,Calendar.JANUARY, 1);
        dayCountofYear.add(Calendar.DAY_OF_YEAR, days);
        System.out.println("GregorianCalendar: "+ dateFormat.format(dayCountofYear.getTime()));
        

        上面的逻辑可以简化为如下的函数调用:

        Date nextDate = addDaysToDate("01/01/2020", 20);
        System.out.println("After Adding Number of Days:"+nextDate); // O/P:21/01/2020
        

        完整示例:

        public class DateHelper {
        
            public static void main(String[] args) throws ParseException {
                int days = 20;
                String initialDay = "01/01/2020";
                Date nextDate = addDaysToDate(initialDay, days);
                System.out.println("After Adding Number of Days:"+nextDate);
        
                /*Date firstDate = DateHelper.parseDate(initialDay, formatStr);
                int daysBetween = getDaysBetween(firstDate, nextDate);
                System.out.println(days + " - Days Between - "+daysBetween);*/
            }
        
            static String formatStr = "dd/MM/yyyy";
            static DateFormat dateFormat = new SimpleDateFormat(formatStr);
            static DateFormat reverseDateFormat = new SimpleDateFormat("yyyy/MM/dd");
        
            public static Date addDaysToDate(String specificDate, int daysCount) throws ParseException {
                Date date = dateFormat.parse(specificDate);
                GregorianCalendar gregCal = (GregorianCalendar) GregorianCalendar.getInstance(); // Current Date
                gregCal.setTime(date); // Change the Date to Provided One
                gregCal.add(Calendar.DAY_OF_YEAR, daysCount);
                Date time = gregCal.getTime();
        
                ZonedDateTime zdt = gregCal.toZonedDateTime();
                System.out.println("GregorianCalendar DayofWeek: "+ zdt.getDayOfWeek());
                return time;
            }
            public static String addDaysToDateStr(String specificDate, int daysCount) throws ParseException {
                String format = dateFormat.format( addDaysToDate(specificDate, daysCount) );
                System.out.println("GregorianCalendar [To a Date added Number of days leads to New Date]: "+ format);
                return format;
            }
            public static Date parseDate(String aSource, String formatStr) throws ParseException {
                DateFormat dateFormat = new SimpleDateFormat(formatStr);
                dateFormat.setLenient(false);
                return dateFormat.parse(aSource);
            }
            public static String formatDate(Date aDate, String formatStr, Calendar calendar) {
                DateFormat dateFormat = new SimpleDateFormat(formatStr);
                dateFormat.setLenient(false);
                dateFormat.setCalendar(calendar);
                return dateFormat.format(aDate);
            }
            public static String formatDate(Date aDate, String formatStr) {
                DateFormat dateFormat = new SimpleDateFormat( formatStr );
                //dateFormat.setCalendar(Calendar.getInstance(TimeZone.getTimeZone("UTF")));
                return dateFormat.format(aDate);
            }
        }
        

        【讨论】:

        • 仅供参考,java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 等存在严重缺陷的日期时间类现在是 legacy,被 Java 8 及更高版本中内置的 java.time 类所取代.建议在 2020 年使用它们是糟糕的建议。
        • 为什么在地球上? SimpleDateFormat 是出了名的麻烦,GregorianCalendar 设计也很糟糕。两者都已经过时了。谁需要在 2020 年使用这些课程得到答案?恕我直言,世界上没有人。
        【解决方案7】:
        Calendar c = Calendar.getInstance();
                 c.set(Calendar.YEAR, 2016);
                 c.set(Calendar.MONTH, 8);
                 c.set(Calendar.DAY_OF_YEAR, 244);
                 c.set(Calendar.HOUR, 0);
                 c.set(Calendar.MINUTE, 0);
                 c.set(Calendar.SECOND, 0);
                 c.set(Calendar.MILLISECOND, 0);
                Date date = c.getTime();
        

        【讨论】:

        • 虽然这段代码 sn-p 可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
        猜你喜欢
        • 2017-06-22
        • 1970-01-01
        • 1970-01-01
        • 2020-01-13
        • 1970-01-01
        • 1970-01-01
        • 2014-05-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多