У меня есть метка времени (64-разрядное целое число), которая представляет количество наносекунд от 0 (представьте себе, как долго работает секундомер). Чтобы проверить это, я использую , то есть 1 year, 2 days, 3 hours, 4 minutes, 5 seconds, 6 milliseconds, and 7 nanoseconds in nanoseconds, и я хочу преобразовать это целое обратно в годы, дни, часы, минуты, секунды, миллисекунды и наносекунды в формате Y:D:H:M:S:m:n
, поэтому я ожидаю увидеть 1:2:3:4:5:6:7
. Я также хочу, чтобы иметь возможность выбирать, какие разрешения я хочу, поэтому, если секундомер будет только измерять время менее часа, я мог бы отображать его как M:S:m
и ожидать от этого 4:5:6
.Как преобразовать временную метку (наносекунды от 0) в Y: D: H: M: S: m: n?
Ниже приведен алгоритм, который я использовал, но он вообще не работает (он возвращает 1:31970222000008:3170222000008:50222000008:222000008:8:8
). Кто-нибудь знает быстрый и надежный способ сделать это? Я хочу, чтобы он выполнял все вычисления менее чем за половину миллисекунды, поэтому секундомер может отображать текущее количество миллисекунд.
public static final byte
YEAR = 0b0100_0000,
DAY = 0b0010_0000,
HOUR = 0b0001_0000,
MINUTE = 0b0000_1000,
SECOND = 0b0000_0100,
MILLISECOND = 0b0000_0010,
NANOSECOND = 0b0000_0001,
RES_DEFAULT = (byte)(MINUTE | SECOND | MILLISECOND);
private static final double
YEAR_IN_DAYS = 365.24219,
DAY_IN_HOURS = 24,
HOUR_IN_MINUTES = 60,
MINUTE_IN_SECONDS = 60,
SECOND_IN_MILLISECONDS = 1000,
MILLISECOND_IN_NANOSECONDS = 1_000_000,
SECOND_IN_NANOSECONDS = SECOND_IN_MILLISECONDS * MILLISECOND_IN_NANOSECONDS,
MINUTE_IN_NANOSECONDS = MINUTE_IN_SECONDS * SECOND_IN_NANOSECONDS,
HOUR_IN_NANOSECONDS = HOUR_IN_MINUTES * MINUTE_IN_NANOSECONDS,
DAY_IN_NANOSECONDS = DAY_IN_HOURS * HOUR_IN_NANOSECONDS,
YEAR_IN_NANOSECONDS = YEAR_IN_DAYS * DAY_IN_NANOSECONDS;
/**
* Converts the given number of nanoseconds from timer 0 to a String in the format
* {@code YYY:DDD:HH:MM:SS:mmmm}
* where all values have leading zeroes. You can choose which values are used with the resFlags, which can be combined bitwise.
* @param timeStamp the number of <B>nano</B>seconds away from timer 0
* @param resFlags the flags representing which levels of resolution to return
* @return the requested timestamp as a String
*/
public static String toString(long timeStamp, byte resFlags)
{
return ""+
((resFlags & YEAR) != 0
? (long)(timeStamp/YEAR_IN_NANOSECONDS)
+ ((resFlags & ~YEAR) != 0
? ":"
: "")
: "")
+ ((resFlags & DAY) != 0
? (long)(timeStamp % DAY_IN_NANOSECONDS)
+ ((resFlags & ~(YEAR | DAY)) != 0
? ":"
: "")
: "")
+ ((resFlags & HOUR) != 0
? (long)(timeStamp % HOUR_IN_NANOSECONDS)
+ ((resFlags & ~(YEAR | DAY | HOUR)) != 0
? ":"
: "")
: "")
+ ((resFlags & MINUTE) != 0
? (long)(timeStamp % MINUTE_IN_NANOSECONDS)
+ ((resFlags & ~(YEAR | DAY | HOUR | MINUTE)) != 0
? ":"
: "")
: "")
+ ((resFlags & SECOND) != 0
? (long)(timeStamp % SECOND_IN_NANOSECONDS)
+ ((resFlags & (MILLISECOND | NANOSECOND)) != 0
? ":"
: "")
: "")
+ ((resFlags & MILLISECOND) != 0
? (long)(timeStamp % MILLISECOND_IN_NANOSECONDS)
+ ((resFlags & NANOSECOND) != 0
? ":"
: "")
: "")
+ ((resFlags & NANOSECOND) != 0
? (long)(timeStamp % 1_000_000)
: "")
;
}
Ваш номер теста неверен. Если он содержит 6 миллисекунд и 7 наносекунд, последние цифры должны быть 006 000,007. – interjay
@interjay вы учли год 365.24219 года? – Supuhstar
А, я думал, вы будете использовать 365 дней в году. Даже вольфрам альфа, который вы связываете, использует 365 дней. – interjay