Skip to content

Commit

Permalink
Merge pull request #250 from eikek/fix-timezone
Browse files Browse the repository at this point in the history
Fix handling time zones
  • Loading branch information
eikek committed Feb 28, 2022
2 parents 11c482f + 2f3f418 commit 2e4d0e7
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,10 @@ Mon *-*-* *:10,20,50

1900-01-* 12,14:0:0
2021-01-06T20:39:23.001+01:00[Europe/Berlin]

2021-11-15 21:05:00 Europe/Berlin
2021-11-15T21:10:00Z

2021-11-15 21:05:00 Europe/Berlin
2021-11-15T20:00:00Z
2021-11-15T20:05:00Z
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package com.github.eikek.calev

import java.time.Instant
import java.time.LocalDateTime
import java.time.ZoneId
import java.time.ZonedDateTime
import java.time._

final case class CalEvent(
weekday: WeekdayComponent,
Expand Down Expand Up @@ -56,7 +53,7 @@ final case class CalEvent(

object CalEvent {

val UTC = ZoneId.of("UTC")
val UTC: ZoneId = ZoneOffset.UTC

def parse(str: String): Either[String, CalEvent] =
internal.CalEventParser.calevent.run(str.trim).map(_._2)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,21 @@ import com.github.eikek.calev._
object DefaultTrigger extends Trigger {

def next(ref: ZonedDateTime, ev: CalEvent): Option[ZonedDateTime] = {
val refDate = {
val (refDate, zone) = {
val date = ev.zone
.map(z => ref.withZoneSameInstant(z))
.getOrElse(ref)
DateTime(date.toLocalDateTime)
(DateTime(date.toLocalDateTime), date.getZone)
}

@annotation.tailrec
def go(c: Calc): Option[ZonedDateTime] =
run(c) match {
case Some(dt) =>
val zd = dt.toLocalDateTime.atZone(ref.getZone)
if (ev.weekday.contains(Weekday.from(zd.getDayOfWeek))) Some(zd)
val zd = dt.toLocalDateTime.atZone(zone)
// need to match weekdays in the zone of the calendar-event
if (ev.weekday.contains(Weekday.from(zd.getDayOfWeek)))
Some(zd.withZoneSameInstant(ref.getZone))
else go(Calc.init(dt, ev))
case None =>
None
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package com.github.eikek.calev

import java.time.LocalDate
import java.time.LocalTime
import java.time.ZonedDateTime
import java.time._
import java.time.temporal.ChronoField

import com.github.eikek.calev.Dsl._
Expand Down Expand Up @@ -67,6 +65,21 @@ class CalEventTest extends FunSuite {
assertEquals(ce.nextElapses(ref, 5), expect)
}

test("nextElapse honors time zones") {
val ref = zdt(2022, 2, 28, 21, 5, 15)

val ce = CalEvent(
AllWeekdays,
DateEvent.All,
time(22.c, 10.c, 0.c),
Some(ZoneId.of("Europe/Berlin"))
)

val Some(next) = ce.nextElapse(ref)
assertEquals(next.getZone, ZoneOffset.UTC)
assertEquals(next.toLocalTime, LocalTime.of(21, 10, 0))
}

private def zdt(y: Int, month: Int, d: Int, h: Int, min: Int, sec: Int): ZonedDateTime =
ZonedDateTime.of(LocalDate.of(y, month, d), LocalTime.of(h, min, sec), CalEvent.UTC)
ZonedDateTime.of(LocalDate.of(y, month, d), LocalTime.of(h, min, sec), ZoneOffset.UTC)
}

0 comments on commit 2e4d0e7

Please sign in to comment.