I have a date in this format: 12 May 2017 09:04:26
I want to auto-update the time of my Mac from this string with a command line.
The first way I found is to use date
command line, as explained in Apple's date manpage, the accepted format is [[[mm]dd]HH]MM[[cc]yy][.ss]
(or {month}{day}{hours}{minutes}{century}{year}.{seconds}).
The second way I found is to use systemsetup command, with setdate
or settime
flags. Accepted formats are: mm:dd:yy
(or {month}:{day}:{year}) for setdate
and hh:mm:ss
(or {hour}:{minutes}:{seconds}) for settime
.
First question: what is the best solution to update time?
And how can I convert (with AppleScript or Bash Script or other method) the first string to a valid format for date
or systemsetup
?
The date
manpage talking about strptime
command but I don't know how can I use it.
Update (after @klanomath answer)
Here is the script I'm using to update my system time when it's wrong (in my case sometimes date go back to 2013). Script is checking some ntp servers with ntpdate
and sntp
commands and if not works, trying to get the date of google.com http header to set it with date
and systemsetup
commands.
#!/bin/bash
# Uncomment for debug
#set -x
# Check if bad year
is_2013() {
YEAR=$(sudo /usr/sbin/systemsetup -getdate | cut -d '/' -f 3)
if [ $YEAR == "2013" ]; then return 0; else return 1; fi
}
http_date_ud() {
# First method, update system time with "date" command
sudo date -f "%a, %d %b %Y %H:%M:%S %Z" "$1"
# Second method, update system time with "systemsetup" command
if is_2013 $1; then
NDATE=$(date -j -f "%a, %d %b %Y %H:%M:%S %Z" "$1" "+%m:%d:%y")
printf "$NDATE"
NTIME=$(echo "$1" | cut -d' ' -f5)
printf "$NTIME"
sudo /usr/sbin/systemsetup -setusingnetworktime off
sudo /usr/sbin/systemsetup -setdate $NDATE
sudo /usr/sbin/systemsetup -settime $NTIME
sudo /usr/sbin/systemsetup -setusingnetworktime on
fi
}
# 1°/ Trying with ntpdate on Apple + NTP global time servers
if is_2013 $1; then ntpdate -t 4 -u time.apple.com; else exit 0; fi
if is_2013 $1; then ntpdate -t 4 -u pool.ntp.org; else exit 0; fi
# 2°/ Trying with sntp with Apple + NTP local time servers
if is_2013 $1; then sntp -s time.euro.apple.com; else exit 0; fi
if is_2013 $1; then sntp -s fr.pool.ntp.org; else exit 0; fi
# 3°/ Trying with HTTP header
HTTP_DATE=$(wget -qSO- --max-redirect=0 google.com 2>&1 | grep Date: | cut -d' ' -f4-9)
lc_tmp=$LC_ALL && LC_ALL=C
http_date_ud "$HTTP_DATE"
LC_ALL=lc_tmp
Best Answer
To properly set a more or less current system date and time with
date
andwget
use:Using
... cut -d' ' -f5-8)"
(see your comment) will omit the time zone and you would have to add 1 or 2 hours depending on the state of the day light saving time to adjust your local time.The result of
wget -qSO- --max-redirect=0 google.com 2>&1 | grep Date: | cut -d' ' -f5-9
is something like 12 May 2017 12:17:00 GMT.So the date/time format of the date command to set date/time has to be
%d %b %Y %H:%M:%S %Z
. Since May is the short as well as the long name of the month and we don't really know the format of the month's name in Google's reply, %b may have to be replaced by %B in June :-).Due to retention and other deficiencies this is not very accurate and the ∂ is up to 3.5 seconds (usually 0.32 seconds here) compared to the time received via ntp.
To get rid of the sntp error mentioned in your comment, do the following:
Now
sntp fr.pool.ntp.org
andsudo sntp -s fr.pool.ntp.org
should work.