java - 计算到目前为止每 15 分钟一段时间的成本

标签 java java-time

我希望用户能够获取有关应用程序使用时间的最新费用。到目前为止,每 15 分钟的时间段都以 10 个货币单位定价。

我只关心耗时。与四分之一小时(0-15、15-30、30-45、45-0 分钟)对齐并不是目标。

例如,一开始,成本为0单位。五分钟后,仍然是 0 单位。 17 分钟后,当前成本为 20 单位(10 单位货币 * 完成的单个 15 分钟时间 block )。 33 分钟后,当前成本为 20 个单位,因为到目前为止已经过了 2 个时间段,每个时间段为 15 分钟。

当前小于 15 分钟的最后一段时间将被忽略。否pro rata

最佳答案

tl;博士

Duration                       // Represent a span-of-time not attached to the timeline. Internally, this class stores a number of whole seconds plus a fractional second as a count of nanoseconds.
.between(                      // Calculate elapsed time. 
    start ,                    // Starting moment captured a while ago using `Instant.now()` call.
    Instant.now()              // Capture the current moment.
)                              // Returns a `Duration` object.
.dividedBy(                    // Get whole number (ignoring remainder) of number of 15-minute chunks occurred within that previous `Duration`. 
    Duration.ofMinutes( 15 )   // Another `Duration` object, our 15-minute chunk definition.
)                              // Returns a `long`, a 64-bit integer.
*                              // Multiply our number of chunks of 15-minutes by the price-per-chunk.
price

详细信息

仅使用 java.time 中的类包,定义于 JSR 310 。避免糟糕的遗留日期时间类(DateCalendar)。

捕捉开始时刻。使用Instant类,代表 UTC 中的一个时刻,分辨率精细为 nanoseconds

Instant start = Instant.now() ;  

编写一个方法来计算耗时的成本。在这个方法中:

  • 首先我们获取耗时,即从开始时刻到当前时刻的时间量。我们在 UTC 中执行此操作,因为涉及时区没有任何好处。我们将耗时表示为 Duration .
  • 其次,我们计算已用时间的完整 block 。我们使用Duration定义我们充电的时间 block ,15分钟。又上课了。然后我们调用Duration::dividedBy获取已完成 block 的计数。
  • 第三,我们通过将单价乘以耗时 block 总数来计算成本。如果您使用小数货币(例如美元或加元)而不是整数,请使用 BigDecimal 而不是 Integer。搜索 Stack Overflow 以获取更多信息,因为这已经被介绍过很多次了。

注意 Math.toIntExact 的使用从 64 位 long 截断为 32 位 int,但如果发生溢出则抛出异常。

代码。

public Integer calculateCostForElapsedTimeSoFar ( final Instant start , final Integer price )
{
    // Determine elapsed time.
    Instant now = Instant.now();
    Duration elapsed = Duration.between( start , now );

    // See how many chunks of 15 minutes have occurred.
    Duration chunk = Duration.ofMinutes( 15 ); // Charge for every chunk of time in chunks of 15 minutes. You could make this a constant instead of a local variable.
    int chunks = Math.toIntExact( elapsed.dividedBy( chunk ) );   // Returns number of whole times a specified Duration occurs within this Duration.

    // Calculate charges.
    Integer cost = ( price * chunks );
    return cost;
}

使用示例。

final Instant start = Instant.now().minus( Duration.ofMinutes( 21 ) );
final Integer price = 10;   // This may come from some other place, such as a look-up in a database.
Integer cost = this.calculateCostForElapsedTimeSoFar( start , price );
System.out.println( "cost: " + cost );

查看此code run live at IdeOne.com .

cost: 10

如果您想自动更新当前成本的显示,而不需要用户执行单击按钮等操作,请了解 Executors framework内置于 Java 中。具体参见ScheduledExecutorService 。并了解如何在特定用户界面框架中异步更新小部件( VaadinJavaFXSwing 等)。同样,请搜索 Stack Overflow 以获取更多信息,因为这两个主题已经被讨论过很多次了。

如果您担心主机上的时钟被重置,请参阅替代方案 approach by user2023577

关于java - 计算到目前为止每 15 分钟一段时间的成本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59418556/

相关文章:

Java 测试扫描仪与假用户输入

java - 无法使用 JSch 连接到服务器端口 23

java - 有没有办法表达 TemporalAmount 的 "sign"?

java - 如何在 Java 8 中正确使用 ZoneOffset、ZoneId 和 LocalDateTime?

java - 如何在java或任何其他工具中将具有不同节点结构的多个xml文件合并到单个xml文件中?

java - 迁移到甲骨文

java - EasyXls getValue() 返回公式的结果

java - 为什么gson在序列化java.time.ZoneId的时候要找java.time.ZoneRegion?

Java 8 DateTimeFormatter 忽略毫秒和区域

java - 获取一周中给定日期的下一个 LocalDateTime