Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

The current time in Los Angeles is 18:05. But when I run TZ=UTC-8 date --iso=ns, I get:

2013-12-07T10:05:37,788173835+0800

The date utility tells me that the time is 10:05, and even says that it's reporting it as UTC+8. Why?

share|improve this question
add comment

3 Answers

up vote 9 down vote accepted

The reason is that TZ=UTC-8 is interpreted as a POSIX time zone. In the POSIX timezone format, the 3 letters are the timezone abbreviation (which is arbitrary) and the number is the number of hours the timezone is behind UTC. So UTC-8 means a timezone abbreviated "UTC" that is −8 hours behind the real UTC, or UTC + 8 hours.

(It works that way because Unix was developed in the US, which is behind UTC. This format allows the US timezones to be represented as EST5, CST6, etc.)

You can see that's what's happening by these examples:

$ TZ=UTC-8 date +'%Z %z'
UTC +0800
$ TZ=UTC8 date +'%Z %z'
UTC -0800
$ TZ=FOO-8 date +'%Z %z'
FOO +0800

The ISO -0800 timezone format takes the opposite approach, with - indicating the zone is behind UTC, and + indicating the zone is ahead of UTC.

share|improve this answer
    
Ah so what I really wanted was TZ=PST+8 date. Thanks. I also found this explanation under man timezone: "The std string specifies the name of the timezone and must be three or more alphabetic characters. The offset string immediately follows std and specifies the time value to be added to the local time to get Coordinated Universal Time (UTC). The offset is positive if the local timezone is west of the Prime Meridian and negative if it is east. The hour must be between 0 and 24, and the minutes and seconds 0 and 59." –  Alex Henrie Dec 7 '13 at 2:55
1  
@Alex no, what you really want is TZ=America/Los_Angeles. You are forgetting that Pacific time is -7 during daylight saving time. –  Matt Johnson Dec 7 '13 at 8:13
2  
@MattJohnson, you mean TZ=:America/Los_Angeles. The colon indicates that it's an Olson timezone file. And in another comment, he mentioned he wanted to ignore daylight saving time, which that would not do. –  cjm Dec 7 '13 at 11:32
    
@cjm, Thanks, you are right about the colon, and I hadn't seen that comment. –  Matt Johnson Dec 7 '13 at 17:30
add comment

Whenever you specify a timezone in the format of +/-00:00, you are specifying an offset, not the actual timezone. From the GNU libc documentation (which follows the POSIX standard):

The offset specifies the time value you must add to the local time to get a Coordinated Universal Time value. It has syntax like [+|-]hh[:mm[:ss]]. This is positive if the local time zone is west of the Prime Meridian and negative if it is east. The hour must be between 0 and 23, and the minute and seconds between 0 and 59.

This is why it appears to be the reverse of what you expect.

share|improve this answer
add comment

As an alternative method you can use the command zdump to show the current time in other timezones + offsets.

Zdump prints the current time in each zonename named on the command line.

The same rules apply with the timezones; west of the prime meridian being "behind" while to the east being "ahead".

Example

$ zdump PST PST Sat Dec 7 03:25:27 2013 PST

I made this script to show several of the timezones + offsets that we're interested in using zdump and date so we could compare them.

$ cat cmd.bash
#!/bin/bash

printf "\ndate: %s\n\n" "$(date)"

for tz in EST PST PST+8 PST-8 UTC UTC+8 UTC-8; do
  echo "-- timezone $tz"
  printf "zdump: %s\n" "$(zdump $tz)"
  printf "date:         %s\n" "$(TZ=$tz date +'%a %b %d %T %Y - (%Z %z)')"
  echo ""
done

Then when you run it you can see the comparison of zdump to date:

$ ./cmd.bash 

date: Sat Dec  7 02:59:05 EST 2013

-- timezone EST
zdump: EST  Sat Dec  7 02:59:05 2013 EST
date:         Sat Dec 07 02:59:05 2013 - (EST -0500)

-- timezone PST
zdump: PST  Sat Dec  7 07:59:05 2013 PST
date:         Sat Dec 07 07:59:05 2013 - (PST +0000)

-- timezone PST+8
zdump: PST+8  Fri Dec  6 23:59:05 2013 PST
date:         Fri Dec 06 23:59:05 2013 - (PST -0800)

-- timezone PST-8
zdump: PST-8  Sat Dec  7 15:59:05 2013 PST
date:         Sat Dec 07 15:59:05 2013 - (PST +0800)

-- timezone UTC
zdump: UTC  Sat Dec  7 07:59:05 2013 UTC
date:         Sat Dec 07 07:59:05 2013 - (UTC +0000)

-- timezone UTC+8
zdump: UTC+8  Fri Dec  6 23:59:05 2013 UTC
date:         Fri Dec 06 23:59:05 2013 - (UTC -0800)

-- timezone UTC-8
zdump: UTC-8  Sat Dec  7 15:59:05 2013 UTC
date:         Sat Dec 07 15:59:05 2013 - (UTC +0800)
share|improve this answer
    
I'm actually trying to get the current time in Pacific Standard Time, ignoring Daylight Savings. –  Alex Henrie Dec 7 '13 at 2:41
1  
I had to downvote this one because you are guessing that "UTC-8" is incorrect. It is correct, it just doesn't do what the user expects. I don't feel that it answers the question as to why it works that way. –  jordanm Dec 7 '13 at 2:41
    
@jordanm - see the clean up. –  slm Dec 7 '13 at 2:50
1  
It still explains what is happening but not why and "why" is what OP is asking. I will remove my downvote but I still don't feel like it is a good answer to the question. –  jordanm Dec 7 '13 at 2:53
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.