我希望用户能够获取有关应用程序使用时间的最新费用。到目前为止,每 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 。避免糟糕的遗留日期时间类(Date
、Calendar
)。
捕捉开始时刻。使用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
。并了解如何在特定用户界面框架中异步更新小部件( Vaadin 、 JavaFX 、 Swing 等)。同样,请搜索 Stack Overflow 以获取更多信息,因为这两个主题已经被讨论过很多次了。
如果您担心主机上的时钟被重置,请参阅替代方案 approach by user2023577 。
关于java - 计算到目前为止每 15 分钟一段时间的成本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59418556/