简体   繁体   English

Java如何在不使用外部库的情况下从毫秒获取月份

[英]Java How to get Month from milliseconds WITHOUT using external Libraries

I am using System.currentTimeMillis() to get number of milliseconds since 1970, I am able to get current Hour, Minute, seconds and year. 我使用System.currentTimeMillis()来获得自1970年以来的毫秒数,我能够获得当前的小时,分​​钟,秒和年。 For example I am getting Year using following formula and it returns 2015: 例如,我使用以下公式获得年份,并返回2015年:

          ((((currTimeInMilliSec / 1000) / 3600) / 24) / 365) + 1970

But how can I calculate Month from milliseconds keeping in considering Leap Year and different number of days in different months like 28,29,30,31. 但是我如何计算月份,从毫秒开始计算闰年和不同月份的不同天数,如28,29,30,31。

Note: For some reason, I need to use only currentTimeMillis function to calculate and I don't want to use other functions or external libraries. 注意:由于某种原因,我只需要使用currentTimeMillis函数来计算,我不想使用其他函数或外部库。 Also I have gone through related posts but didn't find exact answer. 此外,我已经通过相关的帖子,但没有找到确切的答案。

Use GregorianCalendar. 使用GregorianCalendar。

GregorianCalendar c = new GregorianCalendar();

c.setTimeInMillis(1l);

int month = c.get(Calendar.MONTH);

This returns 0, that is January. 这将返回0,即1月。 Imagine an array with the 12 months of the year. 想象一下一年中有12个月的阵列。

Yes, this is possible. 是的,这是可能的。

There are astronomical algorithms that enable the numerical translation between a Julian Day Number and a date-time stamp. 有天文算法可以实现朱利安日数和日期时间戳之间的数字转换。 The algorithm with which I am familiar was published by J. Meeus in his Astronomical Algorithms, 2nd Ed. 我熟悉的算法由J. Meeus在他的Astronomical Algorithms,2nd Ed。中发表。 This algorithm will convert a Julian Day Number to a vector of integers representing the corresponding: 该算法将朱利安日数转换为表示相应的整数向量:

  • YEAR
  • MONTH_IN_YEAR (1-12) MONTH_IN_YEAR(1-12)
  • DAY_IN_MONTH (1-28,29,30,31 as appropriate) DAY_IN_MONTH(1-28,29,30,31)
  • HOUR_IN_DAY (0-23) HOUR_IN_DAY(0-23)
  • MINUTE_IN_HOUR (0-59) MINUTE_IN_HOUR(0-59)
  • SECOND_IN_MINUTE (0-59) SECOND_IN_MINUTE(0-59)
  • MILLISECOND_IN_SECOND (0-999) MILLISECOND_IN_SECOND(0-999)

Because both POSIX time and Julian Day Numbers are date serials (counts of consecutive time units) they are trivial to interconvert. 因为POSIX时间和Julian日数都是日期序列(连续时间单位的数量),所以它们互相转换是微不足道的。 Thus, the 1st step for using this algorithm would be to convert POSIX time (millis since midnight Jan 1, 1970) to a Julian Day Number (count of days since November 24, 4714 BC, in the proleptic Gregorian calendar). 因此,使用该算法的第一步是将POSIX时间(自1970年1月1日午夜以来的毫秒)转换为朱利安日数(自公元前4714年11月24日起,在公历中的公历)。 This is trivial to do since you simply convert from millis to days and adjust the epoch. 这很简单,因为您只需将毫秒转换为几天并调整时期。

Here are the constants: 以下是常量:

/** Accessor index for year field from a date/time vector of ints. */
public static final int YEAR = 0;

/** Accessor index for month-in-year field from a date/time vector of ints */
public static final int MONTH = 1;

/** Accessor index for day-in-month field from a date/time vector of ints */
public static final int DAY = 2;

/** Accessor index for hour-in-day field from a date/time vector of ints */
public static final int HOURS = 3;

/** Accessor index for minute-in-hour field from a date/time vector of ints */
public static final int MINUTES = 4;

/** Accessor index for second-in-minute field from a date/time vector of ints */
public static final int SECONDS = 5;

/** Accessor index for millis-in-second field from a date/time vector of ints */
public static final int MILLIS = 6;

/** The POSIX Epoch represented as a modified Julian Day number */
public static final double POSIX_EPOCH_AS_MJD = 40587.0d;

And here is the method for the algorithm that converts a Julian Day Number (supplied as a double ) to a vector of integers. 以下是将Julian Day Number(作为double )转换为整数向量的算法。 In the code below, you can substitute the trunc() function with Math.floor() and retain the correct behavior: 在下面的代码中,您可以将trunc()函数替换为Math.floor()并保留正确的行为:

public static int[] toVectorFromDayNumber(double julianDay) {

    int[] ymd_hmsm = {YEAR, MONTH, DAY, HOURS, MINUTES, SECONDS, MILLIS};
    int a, b, c, d, e, z;
    double f, x;

    double jd = julianDay + 0.5;

    z = (int) trunc(jd);
    f = (jd - z) + (0.5 / (86400.0 * 1000.0));

    if (z >= 2299161) {
        int alpha = (int) trunc((z - 1867216.25) / 36524.25);
        a = z + 1 + alpha - (alpha / 4);
    } else {
        a = z;
    }

    b = a + 1524;
    c = (int) trunc((b - 122.1) / 365.25);
    d = (int) trunc(365.25 * c);
    e = (int) trunc((b - d) / 30.6001);

    ymd_hmsm[DAY] = b - d - (int) trunc(30.6001 * e);
    ymd_hmsm[MONTH] = (e < 14) 
            ? (e - 1) 
            : (e - 13);
    ymd_hmsm[YEAR] = (ymd_hmsm[MONTH] > 2) 
            ? (c - 4716) 
            : (c - 4715);

    for (int i = HOURS; i <= MILLIS; i++) {
        switch (i) {
            case HOURS:
                f = f * 24.0;
                break;
            case MINUTES:  case SECONDS:
                f = f * 60.0;
                break;
            case MILLIS:
                f = f * 1000.0;
                break;
        }
        x = trunc(f);
        ymd_hmsm[i] = (int) x;
        f = f - x;
    }
    return ymd_hmsm;
}

For example, if the function is called with the Julian Day Number 2457272.5, it would return the following vector of integers representing midnight, Sept 7, 2015 (Labor Day) in UTC: 例如,如果使用Julian Day Number 2457272.5调用该函数,它将返回以UTC表示午夜,2015年9月7日(劳动节)的以下整数向量:

[ 2015, 9, 7, 0, 0, 0, 0 ] [2015,9,7,0,0,0,0]

Edit: A remarkable thing about the Meeus algorithm is that it correctly accounts for both Leap Years and century days (including the century day exception). 编辑:关于Meeus算法的一个值得注意的事情是它正确地解释了闰年和世纪日(包括世纪日例外)。 It uses only integer and floating point arithmetic and is very likely to be more performant than solutions which require object instantiations from the Java Calendar or Date-Time APIs. 它仅使用整数和浮点运算,并且很可能比需要Java日历或日期时间API的对象实例化的解决方案更具性能。

My variant: 我的变种:

public class Main  {

    public static class MyDate {
        int month;
        int day;

        public MyDate(int month, int day) {
            this.month = month;
            this.day = day;
        }
    }

    public static final int[] daysInMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

    public static void main(String[] args) {
        long millis = System.currentTimeMillis();
        long days = millis / 86400000;
        long millisToday = millis % 86400000;
        int yearsPassedApprox = (int) days / 365;
        int daysPassedThisYear = (int) (days - (yearsPassedApprox * 365 + leapYearsCount(yearsPassedApprox)));
        int year = yearsPassedApprox + 1970;
        MyDate myDate = getMonthAndDay(year, daysPassedThisYear);
        int hours = (int) (millisToday / 3600000);
        int minutes = (int) ((millisToday % 3600000) / 60000);
        int seconds = (int) ((millisToday % 60000) / 1000);


        System.out.println("Year: " + year);
        System.out.println("Month: " + myDate.month);
        System.out.println("Day: " + myDate.day);
        System.out.println("Hour: " + hours);
        System.out.println("Minutes: " + minutes);
        System.out.println("Seconds: " + seconds);
    }

    public static MyDate getMonthAndDay(int year, int daysPassedThisYear) {
        int i;
        int daysLeft = daysPassedThisYear;
        boolean leapYear = isLeapYear(year);
        for (i = 0; i < daysInMonth.length; i++) {
            int days = daysInMonth[i];
            if (leapYear && i == 1) {
                days++;
            }
            if (days <= daysLeft) {
                daysLeft -= days;
            } else {
                break;
            }
        }
        return new MyDate(i + 1, daysLeft + 1);
    }

    public static int leapYearsCount(long yearsPassed) {
        int count = 0;
        for (int i = 1970; i < 1970 + yearsPassed ; i++) {
            if (isLeapYear(i)) {
                count++;
            }
        }
        return count;
    }

    public static boolean isLeapYear(int year) {
        return (year % 4 == 0 && !(year % 100 == 0)) || year % 400 == 0;
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 "如何从 Java 8 中的 LocalDateTime 获取毫秒数" - How to get milliseconds from LocalDateTime in Java 8 在Java中使用外部库 - Using external libraries in Java 通过正则表达式或至少在没有外部库的情况下从 Java 中的 html 内容中获取推文 - Get a tweet from html content in Java through either regex or at least without external libraries 使用简单的可运行线程从android studio中的php获取结果,而无需任何外部库 - Get result from php in android studio using simple runnable threads without any external libraries 是否可以在不使用外部库的情况下用Java动态编译类? - Is it possible to compile a class on the fly in Java without using external libraries? 在Java 9中如何在没有外部库的情况下创建XML文件? - How to create XML file without external libraries in Java 9? 如何在Java中获取当前时刻的年、月、日、小时、分钟、秒和毫秒? - How to get year, month, day, hours, minutes, seconds and milliseconds of the current moment in Java? 如何在不使用Maven的情况下排除Java库? - How to exclude java libraries without using Maven? 如何在不使用IDE的情况下在Java中包含库 - how to include libraries in java without using an IDE 如何在 Java 中以毫秒为单位获取 ISO 格式? - How to get ISO format from time in milliseconds in Java?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM