Timezone in docker container

Currently running v2.0.0-beta.1 in a docker container, and I noticed the timestamps for my assets were in UTC. I realized my timezone was set wrong on the host server, so I fixed that, but the way I normally set the timezone in my docker-compose file wasn’t working.

I hopped on the container and saw that the tzdata package wasn’t installed. Is that necessary for the timezone to get updated properly?

Howdy @Forcetrainer !

There are a couple bits with time zones:

  1. Extracting time zones from your photos and videos correctly.

  2. Rendering times relative to the current timezone (which relies on a properly set TZ or /etc/timezone

For the first bit, when extracting captured-at times, PhotoStructure tries to avoid any assumptions about the current timezone: it’s frequently not set to the current location’s timezone (or at least set to Etc/UTC), so I wrote a bunch of heuristics that PhotoStructure uses to try to find the correct zone for every file. (I’m the author of exiftool-vendored, btw).

For the second bit, (rendering times in the local TZ), it turns out that node doesn’t need tzdata, just TZ to be set:

$ docker exec -it photostructure  sh
/ps/app $ node -e "console.log(new Date().toString())"
Mon Jan 03 2022 17:29:21 GMT-0800 (Pacific Standard Time)
/ps/app $ echo $TZ
America/Los_Angeles

I’ve just updated the docker and docker-compose instructions to include TZ properly. If you’re using the UnRAID template, TZ should already be something that you can configure.

Thanks for the suggestion! I don’t believe anything will need it, but I just added it to the Dockerfile that will ship with v2.1. The package is only 3MB…

We’ll now I’m going down a rabbit hole I never thought I would!

Everything you said makes sense, and it does appear Photostructure is getting the right time zone. The info file included this:


[
  {
    _PhotoStructureVersion: '2.0.0-beta.1',
    capturedAt: {
      date: ExifDateTime {
        year: 2021,
        month: 11,
        day: 30,
        hour: 23,
        minute: 31,
        second: 37,
        millisecond: 0,
        tzoffsetMinutes: -300,
        rawValue: '2021:11:30 23:31:37',
        zoneName: 'America/New_York'
      },

However, in the UI it’s rendering the capture time as 23:31. That’s why I thought maybe the TZ on the server mattered.

TIMEZONES:

rabbit hole GIF

(isn’t that correct? I maybe misunderstanding)

Sorry - I definitely overly confused that.

The time being rendered is the same as the rawValue in the info, which is UTC. The real time should be -5 since the time zone was America/New_York (which Photostructure picked up).

And don’t forget daylight saving changes :slight_smile:

Beer No GIF by de chinezen

Somehow in my career dealing with timezones and daylight saving time has been a recurring theme.

And if you want entertainment, keep leap year in mind when doing date math :slight_smile:

(notr, leap year is NOT just every four years. It’s if the year is evenly divisible by 4, but if it’s evenly divisible by 100 it is NOT, unless it is also evenly divisible by 400. So the year 200 leap year was a once very 400 year exception.

And you thought Y2K was a pain :slight_smile:

(excuse if I managed to word that wrong above :-))

The only time that’s reliably encoded in UTC is the GPS Date/Time tag (because GPS is always UTC/GMT).

The encoded time for images, at least for the vast majority of cameras that I’ve looked at–but there are almost certainly exceptions–is in reference to the local timezone.

Videos, unfortunately, are remarkably inconsistently encoded, and almost never have GPS tags, which help guide a “ground truth” into backing into the correct TZ.

What’s the mimetype of the file we’re looking at here?

Leap seconds + fractional-hour TZ offsets =

Fun Diversion GIF

Here’s the full info for the file. The mimetype is video/quicktime

[
  {
    _PhotoStructureVersion: '2.0.0-beta.1',
    capturedAt: {
      date: ExifDateTime {
        year: 2021,
        month: 11,
        day: 30,
        hour: 23,
        minute: 31,
        second: 37,
        millisecond: 0,
        tzoffsetMinutes: -300,
        rawValue: '2021:11:30 23:31:37',
        zoneName: 'America/New_York'
      },
      localCentiseconds: 2021113023313700,
      precisionMs: 1000,
      src: 'tags:CreateDate'
    },
    dimensions: { height: 1080, width: 1920 },
    duration: 12.0083333333333,
    errors: [],
    filters: {
      accepted: [
        'exifExtFilter',
        'fileSizeFilter',
        'notHiddenCheap',
        'noMediaFilter',
        'hasMimeType',
        'supportedMimeTypeFilter',
        'notRejected',
        'minDimensionsFilter',
        'minVideoDurationFilter'
      ],
      rejected: []
    },
    geohash: 'dr443z',
    geohashNumeric: 426905727,
    ignoredBecause: [],
    imageHash: {
      dominantColors: 'Tan (#D2B48C), Khaki (#C3B091), Beaver (#9F8170), Apricot (#FBCEB1), Blood red (#660000)',
      isGreyscale: false,
      meanHash: 'y8vBwcvLS8cwNDAwMDCwAPP/8dHRlw8B',
      modes: [
        3848, 3617,
        3841, 3621,
        3589, 3845,
        1594
      ]
    },
    Make: 'Apple',
    mimetype: 'video/quicktime',
    Model: 'iPhone 11 Pro Max',
    nativePath: '/ps/library/video-main/2021/2021-11/2021-11-iPhone 11 Pro Max/IMG_3481.MOV',
    needsTranscoding: false,
    rotation: 180,
    sha: 'oT2jeTRBe7dhpvBsHnwPHoAW42EH48kk',
    tags: [
      [ 'Camera', 'Apple', 'iPhone 11 Pro Max' ],
      [
        'When',
        { name: '2021', ordinal: 7979 },
        { displayName: 'Nov', name: '11', ordinal: 2 }
      ],
      [ 'Type', 'Video', 'QuickTime' ],
      [
        'fs',
        'Library',
        'video-main',
        '2021',
        '2021-11',
        '2021-11-iPhone 11 Pro Max'
      ]
    ],
    tz: 'America/New_York',
    tzSource: 'from Lat/Lon',
    uri: 'pslib:/video-main/2021/2021-11/2021-11-iPhone%2011%20Pro%20Max/IMG_3481.MOV',
    validFile: 'OK',
    variantSortCriteria: {
      count: 0,
      fileSize: 14,
      isBrowserSupported: false,
      isCover: false,
      mtime: 13652773,
      resolution: 9,
      schemeIdx: 3,
      uri: 'pslib:/video-main/2021/2021-11/2021-11-iPhone%2011%20Pro%20Max/IMG_3481.MOV'
    }
  }
]

Ugh, so it looks like the EXIF datetime is encoded in utc for this file. Are all your iPhone videos 5 hours wrong within PhotoStructure?

(What would be an elegant way to handle this nonsense? A make/model/mimetype list of “these use utc, shift the date to local if you can”?)

Doing a spot check of my videos across a few iPhone models, yes - it looks like they’re all off by 5 hours.

The capture time is correct when viewing in Photos or on the phone, so I’m guessing they’re looking at some value in the exifdata to calculate the local capture time.

I don’t know if this value is specific to iPhone videos, but looking at the full exif data there is a field “Creation Date” that has the right offset. Here are a few of the time related fields from one of my files:

File Modification Date/Time     : 2021:11:18 15:50:11-05:00
Create Date                     : 2021:11:18 20:50:11
Track Create Date               : 2021:11:18 20:50:11
Media Create Date               : 2021:11:18 20:50:11
Creation Date                   : 2021:11:18 15:50:11-05:00

I’m not the best with exif data and I know different manufacturers will leverage fields differently. Seems like a make/model/mimetype list would be the most accurate, but would require cataloging the various makes/models. Is the creation data, if it exists, something that could be considered more correct than other fields? Or is that potentially just specific to Apple?

1 Like

Oh nice catch! I’d never seen the CreationDate tag: I just checked my test image repository of 10,000 different makes and models, and that tag is only on iPhone movies.

I’ve just added CreationDate to the default captured-at tags: PhotoStructure should prefer that tag if it exists and includes a timezone offset.