时区相关问题

huangapple go评论48阅读模式
英文:

Time Zone Related Issue

问题

我有一个情景,必须根据分配的时间激活/停用一个链接。在这里,酒店需要在入住前48小时(下午3:00)激活链接,并在入住前5小时停用相同的链接。现在,酒店可以位于世界上的任何地方。这可以通过源提供的时区偏移来管理。例如,特定的酒店位于德克萨斯州韦科,偏移量为-2,这意味着比美国东部时间(EDT)提前1小时。现在,在我附上的代码中,链接比预期的提前一个小时禁用。由于入住时间通常是下午3:00,链接应在上午10:00禁用,但实际上在上午9:00禁用。

传递给方法的参数是入住日期和源接收到的偏移量数字。

需要协助调整并使全球所有酒店的1小时时间正确。

public static void main(String[] args) throws ParseException {
    long result = calculateTimeDifference("0","2023-07-13");
    System.out.print("Time Difference Calculated : " + result);
    if(result > 300 && result < 2880){
    System.out.println("Send Upgrade Email Active");
    }
    else {
        System.out.println("Send Upgrade Email Inactive");
    }
}

public static long calculateTimeDifference(String hotelOffset, String CheckInDt) throws ParseException {
    String CheckInTime = "15:00";

    long hoursDifference = 0;
    try {
        // Get current date and time in EDT
        ZoneId edtZoneId = ZoneId.of("America/New_York");
        LocalDateTime currentTime = LocalDateTime.now(edtZoneId);

        // Convert check-in date and time to LocalDateTime
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate checkInLocalDate = LocalDate.parse(CheckInDt, dateFormatter);
        LocalTime checkInLocalTime = LocalTime.parse(CheckInTime);

        // Convert hotel's timezone offset string to minutes
        int offsetValue = Integer.parseInt(hotelOffset);
        int offsetInMinutes = offsetValue * 30;

        // Apply the offset to get the correct zone offset
        ZoneOffset hotelZoneOffset = ZoneOffset.ofTotalSeconds(offsetInMinutes * 60);

        // Combine check-in date and time with hotel's timezone offset
        LocalDateTime checkInDateTime = LocalDateTime.of(checkInLocalDate, checkInLocalTime).atOffset(hotelZoneOffset).toLocalDateTime();

        // Calculate the time difference between current time and check-in time
        hoursDifference = ChronoUnit.MINUTES.between(currentTime, checkInDateTime);

    } catch (Exception e) {
        System.out.println("Parse Exception in calculateTimeDifference -- ");
    }
    return hoursDifference;
}

从OP的评论中复制:

offsetInMinutes = offsetValue * 30 这一行有一个业务要求。让我来解释清楚。实际上,偏移值以字符串形式提供,这是从黄金源获得的计算值。这就像如果偏移值为-2,那么特定酒店比EST时间晚1小时。如果值为0,则酒店与EDT时间相同。

如果酒店的偏移量为-2,那么相对于纽约时间(2023-07-16T04:30),酒店的时间将是2023-07-16T03:30。

英文:

I have a scenario where I have to activate/deactivate a link based on the times assigned. Here a hotel needs to activate the link 48 hours before check-in (15:00 PM) and deactivate the same 5 hours before check-in. Now the hotel can be from any part of the world. This can be managed from time-zone offset provided by the source. Ex - A particular hotel lies in Waco Texas with the offset as -2, which means 1 hour backwards from EDT time US/America. Now in my code that I have attached, the link disables one hour before than expected. As the check-in time is 3:00 PM usually the link should be disabled at 10:00 AM, however it disables as 9:00 AM.

Parameters passed to method is Check-In date and offset number received from source.

Need Assistance on how the time of 1 hour be adjusted and made correct universally for all the hotels across globe.

public static void main(String[] args) throws ParseException {
long result = calculateTimeDifference(&quot;0&quot;,&quot;2023-07-13&quot;);
System.out.print(&quot;Time Difference Calculated : &quot; + result);
if(result &gt; 300 &amp;&amp; result &lt; 2880){
System.out.println(&quot;Send Upgrade Email Active&quot;);
}
else {
System.out.println(&quot;Send Upgrade Email Inactive&quot;);
}
}
public static long calculateTimeDifference(String hotelOffset, String CheckInDt) throws ParseException {
String CheckInTime = &quot;15:00&quot;;
long hoursDifference = 0;
try {
// Get current date and time in EDT
ZoneId edtZoneId = ZoneId.of(&quot;America/New_York&quot;);
LocalDateTime currentTime = LocalDateTime.now(edtZoneId);
// Convert check-in date and time to LocalDateTime
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(&quot;yyyy-MM-dd&quot;);
LocalDate checkInLocalDate = LocalDate.parse(CheckInDt, dateFormatter);
LocalTime checkInLocalTime = LocalTime.parse(CheckInTime);
// Convert hotel&#39;s timezone offset string to minutes
int offsetValue = Integer.parseInt(hotelOffset);
int offsetInMinutes = offsetValue * 30;
// Apply the offset to get the correct zone offset
ZoneOffset hotelZoneOffset = ZoneOffset.ofTotalSeconds(offsetInMinutes * 60);
// Combine check-in date and time with hotel&#39;s timezone offset
LocalDateTime checkInDateTime = LocalDateTime.of(checkInLocalDate, checkInLocalTime).atOffset(hotelZoneOffset).toLocalDateTime();
// Calculate the time difference between current time and check-in time
hoursDifference = ChronoUnit.MINUTES.between(currentTime, checkInDateTime);
} catch (Exception e) {
System.out.println(&quot;Parse Exception in calculateTimeDifference -- &quot;);
}
return hoursDifference;
}

Copied from OP's comment:

> The line offsetInMinutes = offsetValue * 30 has a business
> requirement. Let me explain it clear. Actually the Offset Value that
> is coming as a string, which is a calculated value coming from golden
> source. This is like if offset value comes as -2, then the particular
> hotel is running behind time of 1 hour than EST. If the value is 0,
> then the hotel is same as EDT time. so on

> If a hotel is at offset -2, then wrt to time at New York
> (2023-07-16T04:30 ) then time at hotel would be 2023-07-16T03:30

答案1

得分: 0

首先,有几件事情你必须学会,以便在未来的开发工作中能够顺利进行:

  1. 如果日期字符串已经是 ISO 8601 格式,而这也是 java.time 类型的默认格式,那么你就不需要使用 DateTimeFormatter 来解析它。所以,LocalDate.parse("2023-07-16") 将可以直接工作,而不需要 DateTimeFormatter

  2. 你不需要将时间表示为一个字符串(比如 "15:00")然后再进行格式化;你可以直接使用时间单元,例如 LocalTime.of(15, 0)

  3. 以下这段代码 LocalDateTime.of(checkInLocalDate, checkInLocalTime).atOffset(hotelZoneOffset).toLocalDateTime() 是没有意义的,因为它总是会返回 LocalDateTime.of(checkInLocalDate, checkInLocalTime),也就是说,你对 atOffset 所做的任何操作都会被 toLocalDateTime 给撤销掉。

  4. 对于时间差异,你可以使用 java.time.Duration,它会让你得到不同的时间单元。

针对你的问题,你所需要做的就是将纽约当前的日期时间与 hotelOffset 进行调整,方法是将 hotelOffset 以分钟为单位相加即可。

演示:

public class Main {
    public static void main(String[] args) {
        Duration result = calculateTimeDifference("-2", "2023-07-16");
        System.out.println("计算得到的时间差异:" + result);
        // 你也可以分别获取各种时间单位
        System.out.printf("%d 小时, %d 分钟%n", result.toHoursPart(), result.toMinutesPart());
    }

    static Duration calculateTimeDifference(String hotelOffset, String CheckInDt) {
        LocalDateTime nowInNY = LocalDateTime.now(ZoneId.of("America/New_York"));

        // 将酒店的时区偏移字符串转换为分钟
        int offsetValue = Integer.parseInt(hotelOffset);
        int offsetInMinutes = offsetValue * 30;

        LocalDateTime nowAtHotel = nowInNY.plusMinutes(offsetInMinutes);

        LocalDateTime checkInDateTime = LocalDate.parse(CheckInDt)
                                            .atTime(LocalTime.of(15, 0));

        return Duration.between(nowAtHotel, checkInDateTime);
    }
}

样例运行输出:

计算得到的时间差异:PT50M51.207969S
0 小时, 46 分钟

在线演示

Trail: Date Time 中了解更多关于现代日期时间 API 的信息。

英文:

First of all, there are a few things you must learn for your future development work:

  1. You do not need to use a DateTimeFormatter to parse a date string if it's already in ISO 8601 format which is the default format for java.time types. So, LocalDate.parse(&quot;2023-07-16&quot;) will work without requiring a DateTimeFormatter.
  2. You do not need to specify a time as a String (i.e. &quot;15:00&quot;) and then format it; you can directly use time units e.g. LocalTime.of(15, 0).
  3. The code, LocalDateTime.of(checkInLocalDate, checkInLocalTime).atOffset(hotelZoneOffset).toLocalDateTime() is useless as it will always give you LocalDateTime.of(checkInLocalDate, checkInLocalTime) i.e. whatever you are doing with atOffset is being reverted by toLocalDateTime.
  4. For the time difference, you can use java.time.Duration which will provide you with getting different time units separately.

Coming to your problem, all you need is to adjust the current date-time in New York with the hotelOffset, and you can do it by adding hotelOffset in minutes to it.

Demo:

public class Main {
public static void main(String[] args) {
Duration result = calculateTimeDifference(&quot;-2&quot;, &quot;2023-07-16&quot;);
System.out.println(&quot;Time Difference Calculated : &quot; + result);
// You can get time units also separately
System.out.printf(&quot;%d hours, %d minutes%n&quot;, result.toHoursPart(), result.toMinutesPart());
}
static Duration calculateTimeDifference(String hotelOffset, String CheckInDt) {
LocalDateTime nowInNY = LocalDateTime.now(ZoneId.of(&quot;America/New_York&quot;));
// Convert hotel&#39;s timezone offset string to minutes
int offsetValue = Integer.parseInt(hotelOffset);
int offsetInMinutes = offsetValue * 30;
LocalDateTime nowAtHotel = nowInNY.plusMinutes(offsetInMinutes);
LocalDateTime checkInDateTime = LocalDate.parse(CheckInDt)
.atTime(LocalTime.of(15, 0));
return Duration.between(nowAtHotel, checkInDateTime);
}
}

Output from a sample run:

Time Difference Calculated : PT50M51.207969S
0 hours, 46 minutes

<kbd>ONLINE DEMO</kbd>

Learn more about the modern Date-Time API from Trail: Date Time.

huangapple
  • 本文由 发表于 2023年7月14日 02:01:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76682119.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定