apply new code formatter and save action
This commit is contained in:
@@ -14,271 +14,271 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
*/
|
||||
public class FastISODateParser {
|
||||
|
||||
private final static ConcurrentHashMap<Integer, Long> EPOCH_MILLI_MONTH_OFFSETS = new ConcurrentHashMap<>();
|
||||
private final static ConcurrentHashMap<Integer, Long> EPOCH_MILLI_MONTH_OFFSETS = new ConcurrentHashMap<>();
|
||||
|
||||
private int cached_epochMilliMonthOffsetKey = 0;
|
||||
private long cached_epochMilliMonthOffset = 0;
|
||||
private int cached_epochMilliMonthOffsetKey = 0;
|
||||
private long cached_epochMilliMonthOffset = 0;
|
||||
|
||||
/**
|
||||
* Parsing ISO-8601 like dates, e.g. 2011-12-03T10:15:30.123Z or
|
||||
* 2011-12-03T10:15:30+01:00.
|
||||
*
|
||||
* @param date in ISO-8601 format
|
||||
* @return {@link OffsetDateTime}
|
||||
*/
|
||||
public OffsetDateTime parse(final String date) {
|
||||
try {
|
||||
final int year = Integer.parseInt(date, 0, 4, 10);
|
||||
final int month = Integer.parseInt(date, 5, 7, 10);
|
||||
final int dayOfMonth = Integer.parseInt(date, 8, 10, 10);
|
||||
final int hour = Integer.parseInt(date, 11, 13, 10);
|
||||
final int minute = Integer.parseInt(date, 14, 16, 10);
|
||||
final int second = Integer.parseInt(date, 17, 19, 10);
|
||||
/**
|
||||
* Parsing ISO-8601 like dates, e.g. 2011-12-03T10:15:30.123Z or
|
||||
* 2011-12-03T10:15:30+01:00.
|
||||
*
|
||||
* @param date in ISO-8601 format
|
||||
* @return {@link OffsetDateTime}
|
||||
*/
|
||||
public OffsetDateTime parse(final String date) {
|
||||
try {
|
||||
final int year = Integer.parseInt(date, 0, 4, 10);
|
||||
final int month = Integer.parseInt(date, 5, 7, 10);
|
||||
final int dayOfMonth = Integer.parseInt(date, 8, 10, 10);
|
||||
final int hour = Integer.parseInt(date, 11, 13, 10);
|
||||
final int minute = Integer.parseInt(date, 14, 16, 10);
|
||||
final int second = Integer.parseInt(date, 17, 19, 10);
|
||||
|
||||
final int[] nanosAndCharsRead = parseMilliseconds(date, 19);
|
||||
final int nanos = nanosAndCharsRead[0];
|
||||
final int offsetTimezone = 19 + nanosAndCharsRead[1];
|
||||
final int[] nanosAndCharsRead = parseMilliseconds(date, 19);
|
||||
final int nanos = nanosAndCharsRead[0];
|
||||
final int offsetTimezone = 19 + nanosAndCharsRead[1];
|
||||
|
||||
final ZoneOffset offset = date.charAt(offsetTimezone) == 'Z' ? ZoneOffset.UTC
|
||||
: parseZone(date.subSequence(offsetTimezone, date.length()));
|
||||
return OffsetDateTime.of(year, month, dayOfMonth, hour, minute, second, nanos, offset);
|
||||
} catch (final RuntimeException e) {
|
||||
throw new IllegalArgumentException("'" + date + "' is not an ISO-8601 that can be parsed with "
|
||||
+ FastISODateParser.class.getCanonicalName(), e);
|
||||
}
|
||||
}
|
||||
final ZoneOffset offset = date.charAt(offsetTimezone) == 'Z' ? ZoneOffset.UTC
|
||||
: parseZone(date.subSequence(offsetTimezone, date.length()));
|
||||
return OffsetDateTime.of(year, month, dayOfMonth, hour, minute, second, nanos, offset);
|
||||
} catch (final RuntimeException e) {
|
||||
throw new IllegalArgumentException("'" + date + "' is not an ISO-8601 that can be parsed with "
|
||||
+ FastISODateParser.class.getCanonicalName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public long parseAsEpochMilli(final String date) {
|
||||
try {
|
||||
final long year = parseLong(date, 0, 4);
|
||||
final long month = parseLong(date, 5, 7);
|
||||
final long dayOfMonth = parseLong(date, 8, 10);
|
||||
final long hour = parseLong(date, 11, 13);
|
||||
final long minute = parseLong(date, 14, 16);
|
||||
final long second = parseLong(date, 17, 19);
|
||||
public long parseAsEpochMilli(final String date) {
|
||||
try {
|
||||
final long year = parseLong(date, 0, 4);
|
||||
final long month = parseLong(date, 5, 7);
|
||||
final long dayOfMonth = parseLong(date, 8, 10);
|
||||
final long hour = parseLong(date, 11, 13);
|
||||
final long minute = parseLong(date, 14, 16);
|
||||
final long second = parseLong(date, 17, 19);
|
||||
|
||||
final int[] nanosAndCharsRead = parseMilliseconds(date, 19);
|
||||
final long nanos = nanosAndCharsRead[0];
|
||||
final int offsetTimezone = 19 + nanosAndCharsRead[1];
|
||||
final int[] nanosAndCharsRead = parseMilliseconds(date, 19);
|
||||
final long nanos = nanosAndCharsRead[0];
|
||||
final int offsetTimezone = 19 + nanosAndCharsRead[1];
|
||||
|
||||
final long zoneOffsetMillis = date.charAt(offsetTimezone) == 'Z' ? 0
|
||||
: parseZoneToMillis(date.subSequence(offsetTimezone, date.length()));
|
||||
final long zoneOffsetMillis = date.charAt(offsetTimezone) == 'Z' ? 0
|
||||
: parseZoneToMillis(date.subSequence(offsetTimezone, date.length()));
|
||||
|
||||
final int epochMilliMonthOffsetKey = (int) (year * 12 + month - 1);
|
||||
final long epochMilliMonthOffset;
|
||||
final int epochMilliMonthOffsetKey = (int) (year * 12 + month - 1);
|
||||
final long epochMilliMonthOffset;
|
||||
|
||||
if (cached_epochMilliMonthOffsetKey == epochMilliMonthOffsetKey) {
|
||||
epochMilliMonthOffset = cached_epochMilliMonthOffset;
|
||||
} else {
|
||||
epochMilliMonthOffset = EPOCH_MILLI_MONTH_OFFSETS.computeIfAbsent(epochMilliMonthOffsetKey,
|
||||
FastISODateParser::computeEpochMilliMonthOffset);
|
||||
cached_epochMilliMonthOffsetKey = epochMilliMonthOffsetKey;
|
||||
cached_epochMilliMonthOffset = epochMilliMonthOffset;
|
||||
}
|
||||
if (cached_epochMilliMonthOffsetKey == epochMilliMonthOffsetKey) {
|
||||
epochMilliMonthOffset = cached_epochMilliMonthOffset;
|
||||
} else {
|
||||
epochMilliMonthOffset = EPOCH_MILLI_MONTH_OFFSETS.computeIfAbsent(epochMilliMonthOffsetKey,
|
||||
FastISODateParser::computeEpochMilliMonthOffset);
|
||||
cached_epochMilliMonthOffsetKey = epochMilliMonthOffsetKey;
|
||||
cached_epochMilliMonthOffset = epochMilliMonthOffset;
|
||||
}
|
||||
|
||||
final long epochMilli = epochMilliMonthOffset //
|
||||
+ (dayOfMonth - 1) * 86_400_000 //
|
||||
+ hour * 3_600_000 //
|
||||
+ minute * 60_000 //
|
||||
+ second * 1_000 //
|
||||
+ nanos / 1_000_000//
|
||||
- zoneOffsetMillis;
|
||||
return epochMilli;
|
||||
final long epochMilli = epochMilliMonthOffset //
|
||||
+ (dayOfMonth - 1) * 86_400_000 //
|
||||
+ hour * 3_600_000 //
|
||||
+ minute * 60_000 //
|
||||
+ second * 1_000 //
|
||||
+ nanos / 1_000_000//
|
||||
- zoneOffsetMillis;
|
||||
return epochMilli;
|
||||
|
||||
} catch (final RuntimeException e) {
|
||||
throw new IllegalArgumentException("'" + date + "' is not an ISO-8601 that can be parsed with "
|
||||
+ FastISODateParser.class.getCanonicalName(), e);
|
||||
}
|
||||
}
|
||||
} catch (final RuntimeException e) {
|
||||
throw new IllegalArgumentException("'" + date + "' is not an ISO-8601 that can be parsed with "
|
||||
+ FastISODateParser.class.getCanonicalName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private static Long computeEpochMilliMonthOffset(final int key) {
|
||||
private static Long computeEpochMilliMonthOffset(final int key) {
|
||||
|
||||
final int year = key / 12;
|
||||
final int month = key % 12 + 1;
|
||||
final int year = key / 12;
|
||||
final int month = key % 12 + 1;
|
||||
|
||||
final OffsetDateTime date = OffsetDateTime.of(year, month, 1, 0, 0, 0, 0, ZoneOffset.UTC);
|
||||
final OffsetDateTime date = OffsetDateTime.of(year, month, 1, 0, 0, 0, 0, ZoneOffset.UTC);
|
||||
|
||||
return date.toInstant().toEpochMilli();
|
||||
}
|
||||
return date.toInstant().toEpochMilli();
|
||||
}
|
||||
|
||||
private long parseLong(final String string, final int start, final int end) {
|
||||
long result = 0;
|
||||
for (int i = start; i < end; i++) {
|
||||
// final int c = string.charAt(i);
|
||||
final int c = string.codePointAt(i);
|
||||
if (c < '0' || c > '9') {
|
||||
throw new NumberFormatException(c + " is not a number at offset " + i);
|
||||
}
|
||||
result = result * 10 + (c - '0');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
private long parseLong(final String string, final int start, final int end) {
|
||||
long result = 0;
|
||||
for (int i = start; i < end; i++) {
|
||||
// final int c = string.charAt(i);
|
||||
final int c = string.codePointAt(i);
|
||||
if (c < '0' || c > '9') {
|
||||
throw new NumberFormatException(c + " is not a number at offset " + i);
|
||||
}
|
||||
result = result * 10 + (c - '0');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private int[] parseMilliseconds(final String date, final int start) {
|
||||
int result = 0;
|
||||
int i = start;
|
||||
while (i < date.length()) {
|
||||
final char c = date.charAt(i);
|
||||
i++;
|
||||
if (c == '.') {
|
||||
continue;
|
||||
}
|
||||
if (c < '0' || c > '9') {
|
||||
break;
|
||||
}
|
||||
result = result * 10 + (c - '0');
|
||||
}
|
||||
final int readChars = i - start - 1;
|
||||
private int[] parseMilliseconds(final String date, final int start) {
|
||||
int result = 0;
|
||||
int i = start;
|
||||
while (i < date.length()) {
|
||||
final char c = date.charAt(i);
|
||||
i++;
|
||||
if (c == '.') {
|
||||
continue;
|
||||
}
|
||||
if (c < '0' || c > '9') {
|
||||
break;
|
||||
}
|
||||
result = result * 10 + (c - '0');
|
||||
}
|
||||
final int readChars = i - start - 1;
|
||||
|
||||
while (i <= start + 10) {
|
||||
result *= 10;
|
||||
i++;
|
||||
}
|
||||
while (i <= start + 10) {
|
||||
result *= 10;
|
||||
i++;
|
||||
}
|
||||
|
||||
return new int[] { result, readChars };
|
||||
}
|
||||
return new int[] { result, readChars };
|
||||
}
|
||||
|
||||
private ZoneOffset parseZone(final CharSequence zoneString) {
|
||||
private ZoneOffset parseZone(final CharSequence zoneString) {
|
||||
|
||||
final int hours = Integer.parseInt(zoneString, 0, 3, 10);
|
||||
int minutes = Integer.parseInt(zoneString, 4, 6, 10);
|
||||
final int hours = Integer.parseInt(zoneString, 0, 3, 10);
|
||||
int minutes = Integer.parseInt(zoneString, 4, 6, 10);
|
||||
|
||||
// if hours is negative,then minutes must be too
|
||||
minutes = (hours < 0 ? -1 : 1) * minutes;
|
||||
return ZoneOffset.ofHoursMinutes(hours, minutes);
|
||||
}
|
||||
// if hours is negative,then minutes must be too
|
||||
minutes = (hours < 0 ? -1 : 1) * minutes;
|
||||
return ZoneOffset.ofHoursMinutes(hours, minutes);
|
||||
}
|
||||
|
||||
private long parseZoneToMillis(final CharSequence zoneString) {
|
||||
private long parseZoneToMillis(final CharSequence zoneString) {
|
||||
|
||||
final int hours = Integer.parseInt(zoneString, 0, 3, 10);
|
||||
int minutes = Integer.parseInt(zoneString, 4, 6, 10);
|
||||
final int hours = Integer.parseInt(zoneString, 0, 3, 10);
|
||||
int minutes = Integer.parseInt(zoneString, 4, 6, 10);
|
||||
|
||||
// if hours is negative,then minutes must be too
|
||||
minutes = (hours < 0 ? -1 : 1) * minutes;
|
||||
return hours * 3_600_000 + minutes * 60_000;
|
||||
}
|
||||
// if hours is negative,then minutes must be too
|
||||
minutes = (hours < 0 ? -1 : 1) * minutes;
|
||||
return hours * 3_600_000 + minutes * 60_000;
|
||||
}
|
||||
|
||||
public long parseAsEpochMilli(final byte[] date) {
|
||||
return parseAsEpochMilli(date, 0);
|
||||
}
|
||||
public long parseAsEpochMilli(final byte[] date) {
|
||||
return parseAsEpochMilli(date, 0);
|
||||
}
|
||||
|
||||
public long parseAsEpochMilli(final byte[] date, final int beginIndex) {
|
||||
try {
|
||||
final int yearBegin = beginIndex + 0;
|
||||
final int yearEnd = yearBegin + 4;
|
||||
final int monthBegin = yearEnd + 1;
|
||||
final int dayBegin = monthBegin + 3;
|
||||
final int hourBegin = dayBegin + 3;
|
||||
final int minuteBegin = hourBegin + 3;
|
||||
final int secondBegin = minuteBegin + 3;
|
||||
final int secondEnd = secondBegin + 2;
|
||||
public long parseAsEpochMilli(final byte[] date, final int beginIndex) {
|
||||
try {
|
||||
final int yearBegin = beginIndex + 0;
|
||||
final int yearEnd = yearBegin + 4;
|
||||
final int monthBegin = yearEnd + 1;
|
||||
final int dayBegin = monthBegin + 3;
|
||||
final int hourBegin = dayBegin + 3;
|
||||
final int minuteBegin = hourBegin + 3;
|
||||
final int secondBegin = minuteBegin + 3;
|
||||
final int secondEnd = secondBegin + 2;
|
||||
|
||||
final long year = parseLong(date, yearBegin, yearEnd);
|
||||
final long month = parse2ByteLong(date, monthBegin);
|
||||
final long dayOfMonth = parse2ByteLong(date, dayBegin);
|
||||
final long hour = parse2ByteLong(date, hourBegin);
|
||||
final long minute = parse2ByteLong(date, minuteBegin);
|
||||
final long second = parse2ByteLong(date, secondBegin);
|
||||
final long year = parseLong(date, yearBegin, yearEnd);
|
||||
final long month = parse2ByteLong(date, monthBegin);
|
||||
final long dayOfMonth = parse2ByteLong(date, dayBegin);
|
||||
final long hour = parse2ByteLong(date, hourBegin);
|
||||
final long minute = parse2ByteLong(date, minuteBegin);
|
||||
final long second = parse2ByteLong(date, secondBegin);
|
||||
|
||||
final int[] nanosAndCharsRead = parseMilliseconds(date, secondEnd);
|
||||
final long nanos = nanosAndCharsRead[0];
|
||||
final int offsetTimezone = beginIndex + 19 + nanosAndCharsRead[1];
|
||||
final int[] nanosAndCharsRead = parseMilliseconds(date, secondEnd);
|
||||
final long nanos = nanosAndCharsRead[0];
|
||||
final int offsetTimezone = beginIndex + 19 + nanosAndCharsRead[1];
|
||||
|
||||
final long zoneOffsetMillis = date[offsetTimezone] == 'Z' ? 0 : parseZoneToMillis(date, offsetTimezone);
|
||||
final long zoneOffsetMillis = date[offsetTimezone] == 'Z' ? 0 : parseZoneToMillis(date, offsetTimezone);
|
||||
|
||||
final int epochMilliMonthOffsetKey = (int) (year * 12 + month - 1);
|
||||
final long epochMilliMonthOffset;
|
||||
final int epochMilliMonthOffsetKey = (int) (year * 12 + month - 1);
|
||||
final long epochMilliMonthOffset;
|
||||
|
||||
if (cached_epochMilliMonthOffsetKey == epochMilliMonthOffsetKey) {
|
||||
epochMilliMonthOffset = cached_epochMilliMonthOffset;
|
||||
} else {
|
||||
epochMilliMonthOffset = EPOCH_MILLI_MONTH_OFFSETS.computeIfAbsent(epochMilliMonthOffsetKey,
|
||||
FastISODateParser::computeEpochMilliMonthOffset);
|
||||
cached_epochMilliMonthOffsetKey = epochMilliMonthOffsetKey;
|
||||
cached_epochMilliMonthOffset = epochMilliMonthOffset;
|
||||
}
|
||||
if (cached_epochMilliMonthOffsetKey == epochMilliMonthOffsetKey) {
|
||||
epochMilliMonthOffset = cached_epochMilliMonthOffset;
|
||||
} else {
|
||||
epochMilliMonthOffset = EPOCH_MILLI_MONTH_OFFSETS.computeIfAbsent(epochMilliMonthOffsetKey,
|
||||
FastISODateParser::computeEpochMilliMonthOffset);
|
||||
cached_epochMilliMonthOffsetKey = epochMilliMonthOffsetKey;
|
||||
cached_epochMilliMonthOffset = epochMilliMonthOffset;
|
||||
}
|
||||
|
||||
final long epochMilli = epochMilliMonthOffset //
|
||||
+ (dayOfMonth - 1) * 86_400_000 //
|
||||
+ hour * 3_600_000 //
|
||||
+ minute * 60_000 //
|
||||
+ second * 1_000 //
|
||||
+ nanos / 1_000_000//
|
||||
- zoneOffsetMillis;
|
||||
return epochMilli;
|
||||
final long epochMilli = epochMilliMonthOffset //
|
||||
+ (dayOfMonth - 1) * 86_400_000 //
|
||||
+ hour * 3_600_000 //
|
||||
+ minute * 60_000 //
|
||||
+ second * 1_000 //
|
||||
+ nanos / 1_000_000//
|
||||
- zoneOffsetMillis;
|
||||
return epochMilli;
|
||||
|
||||
} catch (final RuntimeException e) {
|
||||
throw new IllegalArgumentException("'"
|
||||
+ new String(date, beginIndex, date.length - beginIndex, StandardCharsets.UTF_8)
|
||||
+ "' is not an ISO-8601 that can be parsed with " + FastISODateParser.class.getCanonicalName(), e);
|
||||
}
|
||||
}
|
||||
} catch (final RuntimeException e) {
|
||||
throw new IllegalArgumentException("'"
|
||||
+ new String(date, beginIndex, date.length - beginIndex, StandardCharsets.UTF_8)
|
||||
+ "' is not an ISO-8601 that can be parsed with " + FastISODateParser.class.getCanonicalName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private long parseLong(final byte[] bytes, final int start, final int end) {
|
||||
long result = 0;
|
||||
for (int i = start; i < end; i++) {
|
||||
final int c = bytes[i];
|
||||
if (c < '0' || c > '9') // (byte)48 = '0' and (byte)57 = '9'
|
||||
{
|
||||
throw new NumberFormatException(c + " is not a number at offset " + i);
|
||||
}
|
||||
result = result * 10 + (c - '0');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
private long parseLong(final byte[] bytes, final int start, final int end) {
|
||||
long result = 0;
|
||||
for (int i = start; i < end; i++) {
|
||||
final int c = bytes[i];
|
||||
if (c < '0' || c > '9') // (byte)48 = '0' and (byte)57 = '9'
|
||||
{
|
||||
throw new NumberFormatException(c + " is not a number at offset " + i);
|
||||
}
|
||||
result = result * 10 + (c - '0');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private long parse2ByteLong(final byte[] bytes, final int start) {
|
||||
private long parse2ByteLong(final byte[] bytes, final int start) {
|
||||
|
||||
final int c0 = bytes[start];
|
||||
if (c0 < 48 || c0 > 57) // (byte)48 = '0' and (byte)57 = '9'
|
||||
{
|
||||
throw new NumberFormatException(c0 + " is not a number at offset " + start);
|
||||
// throw new NumberFormatException();
|
||||
}
|
||||
long result = c0 - 48;
|
||||
final int c0 = bytes[start];
|
||||
if (c0 < 48 || c0 > 57) // (byte)48 = '0' and (byte)57 = '9'
|
||||
{
|
||||
throw new NumberFormatException(c0 + " is not a number at offset " + start);
|
||||
// throw new NumberFormatException();
|
||||
}
|
||||
long result = c0 - 48;
|
||||
|
||||
final int c1 = bytes[start + 1];
|
||||
if (c1 < 48 || c1 > 57) {
|
||||
throw new NumberFormatException(c1 + " is not a number at offset " + (start + 1));
|
||||
// throw new NumberFormatException();
|
||||
}
|
||||
result = result * 10 + (c1 - 48);
|
||||
final int c1 = bytes[start + 1];
|
||||
if (c1 < 48 || c1 > 57) {
|
||||
throw new NumberFormatException(c1 + " is not a number at offset " + (start + 1));
|
||||
// throw new NumberFormatException();
|
||||
}
|
||||
result = result * 10 + (c1 - 48);
|
||||
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private int[] parseMilliseconds(final byte[] date, final int start) {
|
||||
int result = 0;
|
||||
int i = start;
|
||||
while (i < date.length) {
|
||||
final byte c = date[i];
|
||||
i++;
|
||||
if (c == '.') {
|
||||
continue;
|
||||
}
|
||||
if (c < '0' || c > '9') {
|
||||
break;
|
||||
}
|
||||
result = result * 10 + (c - '0');
|
||||
}
|
||||
final int readChars = i - start - 1;
|
||||
private int[] parseMilliseconds(final byte[] date, final int start) {
|
||||
int result = 0;
|
||||
int i = start;
|
||||
while (i < date.length) {
|
||||
final byte c = date[i];
|
||||
i++;
|
||||
if (c == '.') {
|
||||
continue;
|
||||
}
|
||||
if (c < '0' || c > '9') {
|
||||
break;
|
||||
}
|
||||
result = result * 10 + (c - '0');
|
||||
}
|
||||
final int readChars = i - start - 1;
|
||||
|
||||
while (i <= start + 10) {
|
||||
result *= 10;
|
||||
i++;
|
||||
}
|
||||
while (i <= start + 10) {
|
||||
result *= 10;
|
||||
i++;
|
||||
}
|
||||
|
||||
return new int[] { result, readChars };
|
||||
}
|
||||
return new int[] { result, readChars };
|
||||
}
|
||||
|
||||
private long parseZoneToMillis(final byte[] zoneBytes, final int beginIndex) {
|
||||
private long parseZoneToMillis(final byte[] zoneBytes, final int beginIndex) {
|
||||
|
||||
final String zoneString = new String(zoneBytes, beginIndex, zoneBytes.length - beginIndex);
|
||||
final int hours = Integer.parseInt(zoneString, 0, 3, 10);
|
||||
int minutes = Integer.parseInt(zoneString, 4, 6, 10);
|
||||
// if hours is negative,then minutes must be too
|
||||
minutes = (hours < 0 ? -1 : 1) * minutes;
|
||||
return hours * 3_600_000 + minutes * 60_000;
|
||||
}
|
||||
final String zoneString = new String(zoneBytes, beginIndex, zoneBytes.length - beginIndex);
|
||||
final int hours = Integer.parseInt(zoneString, 0, 3, 10);
|
||||
int minutes = Integer.parseInt(zoneString, 4, 6, 10);
|
||||
// if hours is negative,then minutes must be too
|
||||
minutes = (hours < 0 ? -1 : 1) * minutes;
|
||||
return hours * 3_600_000 + minutes * 60_000;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user