4

对于我的每个用户,我存储一个tzid我将其转换为DateTimeZone关于他们当地时区的持有信息。

我想在当地时间上午 8 点每天向用户发送一封电子邮件;如果上午 8 点由于某种原因(如夏令时班次)而模棱两可,我只需要选择上午 8 点中的一个即可;我不在乎哪个。

我的作业每小时运行一次,我有一个Instant包含作业的最后运行时间,另一个Instant包含作业的下一次运行时间。

鉴于这两个Instant被调用的previousRunandnextRun和被DateTimeZone调用的tz,我将如何确定被localTime调用是否eightAM落在此作业运行的范围内?如果是这样,我需要向用户发送电子邮件。

4

1 回答 1

4

鉴于这两个名为 previousRun 和 nextRun 的 Instant,以及名为 tz 的 DateTimeZone,我将如何确定名为 8AM 的 localTime 是否落在此作业运行的范围内?

我认为,以一般方式执行此操作有些棘手。但是,如果您可以依靠您希望远离午夜的时间,并且您的工作将每小时运行一次(因此,例如,如果它没有在午夜和上午 8 点之间运行,您无需考虑会发生什么)我认为你可以这样做:

public static bool ShouldSendEmail(Instant previousRun, Instant nextRun,
                                   DateTimeZone zone)
{
    // Find the instant at which we should send the email for the day containing
    // the last run.
    LocalDate date = previousRun.InZone(zone).Date;
    LocalDateTime dateTime = date + new LocalTime(8, 0);
    Instant instant = dateTime.InZoneLeniently(zone).ToInstant();

    // Check whether that's between the last instant and the next one.
    return previousRun <= instant && instant < nextRun;
}

您可以查看文档InZoneLeniently以准确检查它会给出什么结果,但听起来您并不介意:这仍然会在包含上午 8 点的一个小时内每天发送一封电子邮件。

没有精确地在一天中的时间对其进行参数化,因为处理一天中的时间可能接近午夜的一般情况会更加困难。

编辑:如果您可以存储“下一个发送日期”,那么这很容易 - 而且您不需要该previousRun部分:

public static bool ShouldSendEmail(LocalDateTime nextDate, Instant nextRun,
                                   DateTimeZone zone, LocalTime timeOfDay)
{
    LocalDateTime nextEmailLocal = nextDate + timeOfDay;
    Instant nextEmailInstant =  nextDateTime.InZoneLeniently(zone).ToInstant();
    return nextRun > nextEmailInstant;
}

基本上就是说,“确定我们下一次要发送电子邮件的时间 - 如果下一次运行将晚于该时间,我们应该现在发送。”

于 2013-10-07T13:03:55.543 回答