LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   Setting time with specific format string (https://www.linuxquestions.org/questions/linux-software-2/setting-time-with-specific-format-string-756627/)

MS3FGX 09-20-2009 05:29 PM

Setting time with specific format string
 
I have looked at the man page and experimented with a few things, but I haven't been able to figure this out.

Can anyone tell me why this works:
Code:

date -u +%T -s "21:25:26"
But this doesn't:
Code:

date -u +%H%M%S -s "212526"
Basically, I want to be able to set the UTC time to a string without having any punctuation. It seems like the second command should work, according to the man page and everything I have read, so I am a little stumped.

This isn't a very serious issue, it is really just something I was playing around with and thought was odd. What I am trying to do is set the system time to the UTC time string that is returned from my GPS every second.

For example, this command reads the NMEA output of the GPS, and returns the UTC time when it is reported (exactly once per second):
Code:

root@T-Bird:/~# awk -F, '/\$GPGGA/ {print $2; exit}' /dev/rfcomm0
221611.000

I want to send that returned string into "date" as quickly as possible, I don't want to waste milliseconds doing any string operations adding in colons and the like. I also need to get "date" to accept nanoseconds in the format string (%N), but one step at a time.

NOTE:
I am aware this is not the proper way to do this, and like I said, this was more of a experiment than anything. The right way to get PPS accuracy on a Linux machine requires kernel patching and some userland utilities, but I wanted to see how close I could get doing it by hand.

michaelk 09-20-2009 06:47 PM

I've seen different formats and do not know how it works with timezone data.

date MMDDhhmm[[CC] YY] [.ss]
CC = century
YY = year
ss = seconds

http://www.oreillynet.com/linux/cmd/cmd.csp?path=d/date

Post back on your results.

MS3FGX 09-20-2009 07:47 PM

The last example looks promising, assuming it works in UTC also:
Code:

Set the date to July 1 (0701), 4 a.m. (0400), 2005 (05):

date 0701040095

I could pull the day, month, year from the local clock before polling the GPS, and it looks like the optional .ss would let me provide the seconds.

The man page for "date" seems to indicate that you can tailor your input the same way you can do for output:
Code:

      -d, --date=STRING
              display time described by STRING, not `now'

            .......

      -s, --set=STRING
              set time described by STRING

But maybe there are inherent limitations to input that isn't mentioned? I will play around with this a bit and see if that works, I think I can get close enough if I pre-fetch the date information and just insert that with the UTC satellite time. The nanosecond field shouldn't matter as the GPS outputs the time exactly on the second, and frankly, getting down to nanosecond accuracy in a Bash script is probably beyond wishful thinking.

michaelk 09-20-2009 08:36 PM

With my Garmin 18 LVC the reference is the one-pulse-per-second output pulse immediately preceding the GPRMC sentence, or whichever sentence is first programed. You can determine the RS-232 transmission latency but it will difficult to determine latencies due to OS.

MS3FGX 09-21-2009 09:28 AM

Well, this actually seems to get pretty close. It may actually be a little closer than my stratum 3 NTP server.

The script:
Code:

#!/bin/sh
# Hackish way to set system time to GPS PPS

# Pre-fetch date info
DATE="$(date +%m%d)"
YEAR="$(date +%y)"

# Pause and return UTC time string as close to PPS as possible:
UTC="$(awk -F, '/\$GPGGA/ {print $2; exit}' /dev/rfcomm0 | cut -c 1-6)"
TIME="$(echo $UTC | cut -c 1-4)"
SECONDS="$(echo $UTC | cut -c 5-6)"

# Put it back together and set the time
date -u $DATE$TIME$YEAR.$SECONDS

To compare the live time from the GPS to system time, I use the following command:
Code:

root@T-Bird:/~# awk -F, '/\$GPGGA/ {print $2; exit}' /dev/rfcomm0 && date -u +%H%M%S.%N | cut -c 1-10
141417.000
141416.993

So this shows system time lagging satellite time by a very slim margin, which I assume is coming from the script itself, plus the inherent latency over the Bluetooth link.

Interestingly, running that same command on my NTP server:
Code:

root@Mainframe:/~# awk -F, '/\$GPGGA/ {print $2; exit}' /dev/rfcomm0 && date -u +%H%M%S.%N | cut -c 1-10
141603.000
141603.366

It would appear that the time is several hundred milliseconds off when set from the Internet (which of course is not very surprising).

While this is a very rough experiment, I wonder what type of results I would get if I ran this script every 15 or 30 minutes on my NTP server rather than pulling time from a stratum 2 server. Perhaps I could even improve the execution speed of this script a bit, I am sure there is a better way to separate the UTC string into HHMM and SS, but I can't think of how.

Shadow_7 09-21-2009 04:50 PM

Would the + part be ignored, since that's for how the date is outputted, not inputted? Beyond that I never really figured out date for setting the date/time. But it does work if you input date and time in two separate commands

date -s "20090921"
date -s "12:31:30.123"

Although I typically just do an

ntpdate time-b.nist.gov

Unless I don't have an internet connection, where I have to do the previous date method.


All times are GMT -5. The time now is 11:12 PM.