Skip to content

Commit

Permalink
Proper handle daylight saving time switching
Browse files Browse the repository at this point in the history
  • Loading branch information
LEOYoon-Tsaw committed Nov 7, 2021
1 parent df46935 commit 7b7da8a
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 30 deletions.
4 changes: 2 additions & 2 deletions ChineseTime.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 25;
CURRENT_PROJECT_VERSION = 26;
DEVELOPMENT_TEAM = 28HU5A7B46;
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = ChineseTime/Info.plist;
Expand All @@ -327,7 +327,7 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 25;
CURRENT_PROJECT_VERSION = 26;
DEVELOPMENT_TEAM = 28HU5A7B46;
ENABLE_HARDENED_RUNTIME = YES;
INFOPLIST_FILE = ChineseTime/Info.plist;
Expand Down
67 changes: 42 additions & 25 deletions ChineseTime/Model.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ import Foundation

private let beijingTime = TimeZone(identifier: "Asia/Shanghai")!

extension Calendar {
func timeInSeconds(for date: Date) -> Double {
var seconds = self.component(.hour, from: date) * 3600
seconds += self.component(.minute, from: date) * 60
seconds += self.component(.second, from: date)
let nanoseconds = self.component(.nanosecond, from: date)
return Double(seconds) + Double(nanoseconds) / 1e9
}
}

private func getJD(yyyy: Int, mm: Int, dd: Int) -> CGFloat {
var m1 = mm
Expand Down Expand Up @@ -264,6 +273,7 @@ class ChineseCalendar {
private let _month: Int
private let _precise_month: Int
private let _day: Int
private var _time_in_seconds: Double
private var _evenSolarTerms: [Date]
private var _oddSolarTerms: [Date]
private var _moonEclipses: [Date]
Expand Down Expand Up @@ -389,6 +399,7 @@ class ChineseCalendar {
self._day = day_index
self._year_start = solar_terms[0]
self._days_in_month = Int(calendar.startOfDay(for: eclipse[month_index]).distance(to: calendar.startOfDay(for: eclipse[month_index+1])) / 3600 / 24 + 0.5)
self._time_in_seconds = _calendar.timeInSeconds(for: time)
}

var dateString: String {
Expand All @@ -401,8 +412,7 @@ class ChineseCalendar {
}
}
var timeString: String {
let time_in_seconds = _calendar.startOfDay(for: _time).distance(to: _time)
let time_in_chinese_minutes = Int(time_in_seconds / 144)
let time_in_chinese_minutes = Int(_time_in_seconds / 144)
let chinese_hour_index = time_in_chinese_minutes / 25
var residual = time_in_chinese_minutes - chinese_hour_index * 25
residual += chinese_hour_index % 6
Expand Down Expand Up @@ -467,7 +477,7 @@ class ChineseCalendar {
}
}
var currentHour: CGFloat {
_calendar.startOfDay(for: _time).distance(to: _time) / 3600
_time_in_seconds / 3600
}
var currentDay: Int {
_day + 1
Expand Down Expand Up @@ -529,37 +539,44 @@ class ChineseCalendar {
}
var eventInDay: CelestialEvent {
let dayStart = _calendar.startOfDay(for: _time)
let nextDayStart = _calendar.date(byAdding: .day, value: 1, to: dayStart)!
var event = CelestialEvent()
event.eclipse = _moonEclipses.map { date in
dayStart.distance(to: date) / 3600 / 24
}.filter { 0 <= $0 && 1 > $0 }
event.fullMoon = _fullMoons.map { date in
dayStart.distance(to: date) / 3600 / 24
}.filter { 0 <= $0 && 1 > $0 }
event.evenSolarTerm = _evenSolarTerms.map { date in
dayStart.distance(to: date) / 3600 / 24
}.filter { 0 <= $0 && 1 > $0 }
event.oddSolarTerm = _oddSolarTerms.map { date in
dayStart.distance(to: date) / 3600 / 24
}.filter { 0 <= $0 && 1 > $0 }
event.eclipse = _moonEclipses.filter { dayStart <= $0 && nextDayStart > $0 }.map { date in
CGFloat(_calendar.timeInSeconds(for: date)) / 3600 / 24
}
event.fullMoon = _fullMoons.filter { dayStart <= $0 && nextDayStart > $0 }.map { date in
CGFloat(_calendar.timeInSeconds(for: date)) / 3600 / 24
}
event.evenSolarTerm = _evenSolarTerms.filter { dayStart <= $0 && nextDayStart > $0 }.map { date in
CGFloat(_calendar.timeInSeconds(for: date)) / 3600 / 24
}
event.oddSolarTerm = _oddSolarTerms.filter { dayStart <= $0 && nextDayStart > $0 }.map { date in
CGFloat(_calendar.timeInSeconds(for: date)) / 3600 / 24
}
return event
}
var eventInHour: CelestialEvent {
let dayStart = _calendar.startOfDay(for: _time)
let hourStart = dayStart.addingTimeInterval(Double(floor(self.currentHour / 2) * 7200))
let currentHour = self.currentHour
let hourStart = _calendar.date(bySettingHour: Int(currentHour / 2) * 2, minute: 0, second: 0, of: _time)!
let nextHourStart: Date
if currentHour / 2 < 11 {
nextHourStart = _calendar.date(bySettingHour: (Int(currentHour / 2)+1) * 2, minute: 0, second: 0, of: _time)!
} else {
nextHourStart = _calendar.startOfDay(for: _calendar.date(byAdding: .day, value: 1, to: _time)!)
}
var event = CelestialEvent()
event.eclipse = _moonEclipses.map { date in
event.eclipse = _moonEclipses.filter { hourStart <= $0 && nextHourStart > $0 }.map { date in
hourStart.distance(to: date) / 7200
}.filter { 0 <= $0 && 1 > $0 }
event.fullMoon = _fullMoons.map { date in
}
event.fullMoon = _fullMoons.filter { hourStart <= $0 && nextHourStart > $0 }.map { date in
hourStart.distance(to: date) / 7200
}.filter { 0 <= $0 && 1 > $0 }
event.evenSolarTerm = _evenSolarTerms.map { date in
}
event.evenSolarTerm = _evenSolarTerms.filter { hourStart <= $0 && nextHourStart > $0 }.map { date in
hourStart.distance(to: date) / 7200
}.filter { 0 <= $0 && 1 > $0 }
event.oddSolarTerm = _oddSolarTerms.map { date in
}
event.oddSolarTerm = _oddSolarTerms.filter { hourStart <= $0 && nextHourStart > $0 }.map { date in
hourStart.distance(to: date) / 7200
}.filter { 0 <= $0 && 1 > $0 }
}
return event
}
}
6 changes: 3 additions & 3 deletions ChineseTime/WatchFace.swift
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ class WatchFaceView: NSView {
func angleMask(angle: CGFloat, in circle: RoundedRect) -> CAShapeLayer {
let radius = sqrt(pow(circle._boundBox.width, 2) + pow(circle._boundBox.height, 2))
let center = NSMakePoint(circle._boundBox.midX, circle._boundBox.midY)
let anglePoint = circle.arcPoints(lambdas: [angle])[0].position
let anglePoint = circle.arcPoints(lambdas: [min(1 - 1e-15, max(0, angle))])[0].position
let angle = atan2(anglePoint.y - center.y, anglePoint.x - center.x)
let endAngle = (CGFloat.pi / 2 - angle) % (CGFloat.pi * 2) - CGFloat.pi / 2
let path = CGMutablePath()
Expand Down Expand Up @@ -402,7 +402,7 @@ class WatchFaceView: NSView {

func drawMark(at locations: [CGFloat], on ring: RoundedRect, maskPath: CGPath, colors: [NSColor], radius: CGFloat) {
let marks = CALayer()
let points = ring.arcPoints(lambdas: locations)
let points = ring.arcPoints(lambdas: locations.filter { 0 <= $0 && 1 >= $0} )
for i in 0..<locations.count {
let point = points[i]
let pos = point.position
Expand Down Expand Up @@ -746,7 +746,7 @@ class WatchFaceView: NSView {
let subQuarterTick = Array(subQuarterTicks).sorted()
let subHourTick = Array(subHourTicks).sorted()

let evenHourText = ChineseCalendar.terrestrial_branches[Int(currentHour / 2)] + ChineseCalendar.sub_hour_name[1]
let evenHourText = ChineseCalendar.terrestrial_branches[Int(currentHour / 2) % 12] + ChineseCalendar.sub_hour_name[1]
let oddHourText = ChineseCalendar.terrestrial_branches[(Int(currentHour / 2)+1) % 12] + ChineseCalendar.sub_hour_name[0]
var subHourTexts = [String]()
var subHourTextsPositions = [CGFloat]()
Expand Down

0 comments on commit 7b7da8a

Please sign in to comment.