122 lines
2.9 KiB
Go
122 lines
2.9 KiB
Go
|
package entity
|
||
|
|
||
|
import (
|
||
|
"strings"
|
||
|
"time"
|
||
|
|
||
|
"github.com/photoprism/photoprism/pkg/txt"
|
||
|
)
|
||
|
|
||
|
// TrustedTime tests if the photo has a known date and time from a trusted source.
|
||
|
func (m *Photo) TrustedTime() bool {
|
||
|
if SrcPriority[m.TakenSrc] <= SrcPriority[SrcEstimate] {
|
||
|
return false
|
||
|
} else if m.TakenAt.IsZero() || m.TakenAtLocal.IsZero() {
|
||
|
return false
|
||
|
} else if m.TimeZone == "" || m.TimeZoneUTC() {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
// SetTakenAt changes the photo date if not empty and from the same source.
|
||
|
func (m *Photo) SetTakenAt(taken, local time.Time, zone, source string) {
|
||
|
if taken.IsZero() || taken.Year() < 1000 || taken.Year() > txt.YearMax {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if SrcPriority[source] < SrcPriority[m.TakenSrc] && !m.TakenAt.IsZero() {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// Remove time zone if time was extracted from file name.
|
||
|
if source == SrcName {
|
||
|
zone = ""
|
||
|
}
|
||
|
|
||
|
// Round times to avoid jitter.
|
||
|
taken = taken.Round(time.Second).UTC()
|
||
|
|
||
|
// Default local time to taken if zero or invalid.
|
||
|
if local.IsZero() || local.Year() < 1000 {
|
||
|
local = taken
|
||
|
} else {
|
||
|
local = local.Round(time.Second)
|
||
|
}
|
||
|
|
||
|
// Don't update older date.
|
||
|
if SrcPriority[source] <= SrcPriority[SrcAuto] && !m.TakenAt.IsZero() && taken.After(m.TakenAt) {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// Set UTC time and date source.
|
||
|
m.TakenAt = taken
|
||
|
m.TakenAtLocal = local
|
||
|
m.TakenSrc = source
|
||
|
|
||
|
if zone == time.UTC.String() && m.TimeZone != "" {
|
||
|
// Location exists, set local time from UTC.
|
||
|
m.TakenAtLocal = m.GetTakenAtLocal()
|
||
|
} else if zone != "" {
|
||
|
// Apply new time zone.
|
||
|
m.TimeZone = zone
|
||
|
m.TakenAt = m.GetTakenAt()
|
||
|
} else if m.TimeZoneUTC() {
|
||
|
// Local is UTC.
|
||
|
m.TimeZone = zone
|
||
|
m.TakenAtLocal = taken
|
||
|
} else if m.TimeZone != "" {
|
||
|
// Apply existing time zone.
|
||
|
m.TakenAt = m.GetTakenAt()
|
||
|
}
|
||
|
|
||
|
m.UpdateDateFields()
|
||
|
}
|
||
|
|
||
|
// TimeZoneUTC tests if the current time zone is UTC.
|
||
|
func (m *Photo) TimeZoneUTC() bool {
|
||
|
return strings.EqualFold(m.TimeZone, time.UTC.String())
|
||
|
}
|
||
|
|
||
|
// UpdateTimeZone updates the time zone.
|
||
|
func (m *Photo) UpdateTimeZone(zone string) {
|
||
|
if zone == "" || zone == time.UTC.String() || zone == m.TimeZone {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if SrcPriority[m.TakenSrc] >= SrcPriority[SrcManual] && m.TimeZone != "" {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if m.TimeZoneUTC() {
|
||
|
m.TimeZone = zone
|
||
|
m.TakenAtLocal = m.GetTakenAtLocal()
|
||
|
} else {
|
||
|
m.TimeZone = zone
|
||
|
m.TakenAt = m.GetTakenAt()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// UpdateDateFields updates internal date fields.
|
||
|
func (m *Photo) UpdateDateFields() {
|
||
|
if m.TakenAt.IsZero() || m.TakenAt.Year() < 1000 {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if m.TakenAtLocal.IsZero() || m.TakenAtLocal.Year() < 1000 {
|
||
|
m.TakenAtLocal = m.TakenAt
|
||
|
}
|
||
|
|
||
|
// Set date to unknown if file system date is about the same as indexing time.
|
||
|
if m.TakenSrc == SrcAuto && m.TakenAt.After(m.CreatedAt.Add(-24*time.Hour)) {
|
||
|
m.PhotoYear = UnknownYear
|
||
|
m.PhotoMonth = UnknownMonth
|
||
|
m.PhotoDay = UnknownDay
|
||
|
} else if m.TakenSrc != SrcManual {
|
||
|
m.PhotoYear = m.TakenAtLocal.Year()
|
||
|
m.PhotoMonth = int(m.TakenAtLocal.Month())
|
||
|
m.PhotoDay = m.TakenAtLocal.Day()
|
||
|
}
|
||
|
}
|