Java 8 Time - 相当于.NET DateTime.MaxValue.Ticks

时间:2016-08-23 23:15:07

标签: java datetime

我已经包含了下面的整个方法,但实际上挑战是在Java 8中模拟DateTime.MaxValue.Ticks。我也不知道Java中的“.ToString(”D19“)的等价物。

我以为我已经想出了如何开始,这是通过使用Instant.MAX.toEpochMilli(),然后我可以乘以10000得到Ticks。可悲的是,这个简单的语句引发了一个异常,所以它是一个非启动者:

  

抓到:java.lang.ArithmeticException:long overflow

这是原始方法。它用于查询Azure存储表以获取历史指标。

// Creates a TableQuery for getting metrics by timestamp
private static TableQuery GenerateMetricTimestampQuery(string partitionKey, DateTime startTime, DateTime endTime)
{
    return GenerateMetricQuery(
        partitionKey,
        (DateTime.MaxValue.Ticks - endTime.Ticks + 1).ToString("D19") + "__",
        (DateTime.MaxValue.Ticks - startTime.Ticks).ToString("D19") + "__");
}

以下是RowKey字段值的示例:

  

2519303419199999999 __

我花了一天时间在这上面,我很难过。任何帮助将不胜感激。

如果可能的话,我宁愿在没有JodaTime的情况下这样做。

UPDATE1 ***基于评论,这是Java中的例外示例。

import java.time.Instant;
public class Tester {
    public static void main(String[] args){
        System.out.println(Instant.MAX.toEpochMilli());
    }
}

2 个答案:

答案 0 :(得分:6)

更新 原始答案未考虑Java纪元(1970)和.NET刻度(0001)之间的偏移差异。更正!

供参考,Long.MAX_VALUE(Java)是:
9,223,372,036,854,775,807

在.NET中,DateTime.MaxValue是:
9999-12-31 23:59:59.9999999
3,155,378,975,999,999,999滴答 1 (约1/3长)

在Java 8中,Instant.MAX是:
+1000000000-12-31 23:59:59.999999999
31,556,889,864,403,199,999,999,999 nanos (溢出很久)
315,568,898,644,031,999,999,999滴答 2 (溢出很久)
31,556,889,864,403,199,999毫秒(溢出很长时间)
31,556,889,864,403,199(约1/292长)

供参考,2519303419199999999的值为:
2016-08-23 13:28:00
636,075,556,800,000,000勾选 1 (约1/14长)
14,719,588,800,000,000滴答 2 (约1/626长)
1)自0001-01-01(.NET)2)自1970-01-01(Java)

如您所见,{ticks'中的Instant.MAX 不适合long。甚至毫秒都不适合。

更重要的是,Instant.MAX DateTime.MaxValue的值相同。

我建议你只为值创建一个常量,例如

public static final long DATETIME_MAXVALUE_TICKS = 3155378975999999999L; // .NET: DateTime.MaxValue.Ticks

这样,您将获得与.NET代码相同的字符串值:

public static final long EPOCH_OFFSET = 62135596800L; // -Instant.parse("0001-01-01T00:00:00Z").getEpochSecond()

private static long getTicks(Instant instant) {
    long seconds = Math.addExact(instant.getEpochSecond(), EPOCH_OFFSET);
    long ticks = Math.multiplyExact(seconds, 10_000_000L);
    return Math.addExact(ticks, instant.getNano() / 100);
}

public static void main(String[] args) {
    Instant startTime = Instant.parse("2016-08-23T13:28:00Z");
    String s = String.format("%19d", DATETIME_MAXVALUE_TICKS - getTicks(startTime));
    System.out.println(s);
}

输出:
2519303419199999999

答案 1 :(得分:0)

long maxSeconds = Instant.MAX.getEpochSecond(); //31556889864403199
int maxNanos = Instant.MAX.getNano(); //999999999

这两个值可以一起用于创建精确的MAX值作为数字: 31556889864403199,999999999

如果您需要打印它,您需要将它们作为String加入。

您还可以从以下两个值创建BigDecimal,如:

BigDecimal max = new BigDecimal(Long.toString(maxSeconds) + "." + String.format("%09d", maxNanos));

并对其进行操作:

BigDecimal now = new BigDecimal(String.format("%d.%09d", Instant.now().getEpochSecond(), Instant.now().getNano()));
System.out.println(max.subtract(now).toString());