31

How to Correct Timezone

Last time, I figured out how to adjust a system clock in vagrant server. However, when I halt the vagrant and start it again, the system clock is always 9 hours late. I can adjust by using ntp command manually, but I'd like to know how to adjust the system clock automatically.

I have tried the below, but it still doesn't work. Are there any suggestions?

How to sync time on host wake-up within VirtualBox?

Community
  • 1
  • 1
Sho
  • 343
  • 1
  • 3
  • 9

9 Answers9

45

The method I use and it should not be provider specific is to add the following in my Vagrantfile

  config.vm.provision :shell, :inline => "sudo rm /etc/localtime && sudo ln -s /usr/share/zoneinfo/Europe/Paris /etc/localtime", run: "always"

you would need to replace '/Europe/Paris' with the timezone you want to set

Frederic Henri
  • 51,761
  • 10
  • 113
  • 139
  • After matching the version of guest addtion, it perfectly works. (I can not see clearly if the version mismatch really matters to this problem ) I think I should learn ruby if I will keep using vagrant. Thanks soooo much! – Sho Nov 28 '15 at 07:25
  • @Sho: you can also use vagrant with shell provisioning scripts or writing them with puppet or chef. you are not forced to use ruby. i am quite happy with shell provisioning. –  Dec 30 '17 at 16:30
  • Apart from this, times were never properly synced in my Ubuntu based guest until I installed the `ntp` package (it was already installed on my host) to get NTP up and running - 'Duh' you might say, but I was assuming the guest additions were supposed to take care of this entirely. Of course, [one should make sure guest additions are installed](https://superuser.com/questions/463106/virtualbox-how-to-sync-host-and-guest-time). – polynomial_donut Jan 10 '19 at 13:35
  • There is a vagrant-timezone plugin, please see this post: https://stackoverflow.com/a/62085199/3164018 – cleary Jun 15 '20 at 02:09
  • 1
    @cleary - correct but it did not exist at the time of the question and it depends if you want to have a large set of plugins or in control of what's happening ... for a 1 line in Vagrantfile I don't prefer to install a plugin – Frederic Henri Jun 15 '20 at 10:23
18

The simplest way is to set the timezone automatically is to use the vagrant-timezone plugin.

Install it once with:

vagrant plugin install vagrant-timezone



After that, add the below to your Vagrantfile:

if Vagrant.has_plugin?("vagrant-timezone")
   config.timezone.value = "UTC"
end

You may replace "UTC" with any of the tz values listed here. For example: "Asia/Kolkata".



Or you can use your host's timezone with this entry in your Vagrantfile:

if Vagrant.has_plugin?("vagrant-timezone")
   config.timezone.value = :host
end
Greg Dubicki
  • 5,983
  • 3
  • 55
  • 68
Priyank Gosalia
  • 6,633
  • 1
  • 10
  • 3
  • Thanks for posting! This seems far and away the most vagrant-like method to do this, I'm surprised that I'm the first upvoter though - this is not a new plugin, going by the github commits, it first began development in 2016 (https://github.com/tmatilai/vagrant-timezone/commits/master) – cleary Jun 15 '20 at 02:08
  • "vagrant plugin install vagrant-timezone" this solved my issue. Thanks. – samir mankar Jun 20 '20 at 12:52
10

Accepted answer is not robust enough, as it does not account for people who travel between timezones, and requires end users to modify Vagrantfile instead of just doing vagrant up.

Building up on Scott P.'s answer, here's a better more flexible solution that matches VM timezone to host's tz automatically. There's a typo/mistake in his snippet's Etc/GMT time zone selection, as per POSIX GMT+7 sets clock 7 hours behind (see Wiki explanation), hence we need to swap offsets:

Vagrant.configure("2") do |config|
require 'time'
offset = ((Time.zone_offset(Time.now.zone) / 60) / 60)
timezone_suffix = offset >= 0 ? "-#{offset.to_s}" : "+#{offset.to_s}"
timezone = 'Etc/GMT' + timezone_suffix
config.vm.provision :shell, :inline => "sudo rm /etc/localtime && sudo ln -s /usr/share/zoneinfo/" + timezone + " /etc/localtime", run: "always"
end
Benny K
  • 1,107
  • 12
  • 9
6

I got:

[vagrant@ansiblecontrol ~]$ date -s \"$(curl -I google.com 2>&1 | grep Date: | cut -d' ' -f3-6)Z\"
date: extra operand ‘2018’
Try 'date --help' for more information.

This works for me:

sudo date -s "$(curl -I google.com 2>&1 | grep Date: | cut -d' ' -f3-6)Z"
Sun Apr  1 16:36:59 CEST 2018

So removed the "\" escape character.

4

A slightly improved version that auto-detects timezone:

The auto-detect portion came from here.

Vagrant.configure("2") do |config|
  require 'time'
  offset = ((Time.zone_offset(Time.now.zone) / 60) / 60)
  timezone_suffix = offset >= 0 ? "+#{offset.to_s}" : "#{offset.to_s}"
  timezone = 'Etc/GMT' + timezone_suffix
  config.vm.provision :shell, :inline => "sudo rm /etc/localtime && sudo ln -s /usr/share/zoneinfo/" + timezone + " /etc/localtime", run: "always"
end
Scott P.
  • 1,054
  • 11
  • 12
3

My Vagrant Guest OS time was out of sync by 7 days. The above methods did not work for me, since Guest additions and ntp were not installed in my Guest machine.

I finally solved the issue by using the hack from https://askubuntu.com/a/683136/119371

cfg.vm.provision "shell", inline: "date -s \"$(wget -qSO- --max-redirect=0 google.com 2>&1 | grep Date: | cut -d' ' -f5-8)Z\"", run: "always", privileged: true, upload_path: "/home/vagrant/tmp/vagrant-shell"

The above method does not sync the Guest OS time with your host machine or any NTP server. It sends an HTTP request to google.com and updates the system time with the time in the HTTP response header field.

Hence, depending on your internet connection speed and latency, the updated time could be off by several milliseconds to a few seconds (usually < 100ms). But it shouldn't matter for most cases.

Following is the curl version, if you don't want to use wget for any reason

cfg.vm.provision "shell", inline: "date -s \"$(curl -I google.com 2>&1 | grep Date: | cut -d' ' -f3-6)Z\""
Community
  • 1
  • 1
Joyce Babu
  • 19,602
  • 13
  • 62
  • 97
2

@Benny K and @Scott P.'s solution giving me the negative value of a timezone, like in @rubo77's case. Worth to note that my host OS is Windows. If timedatectl is present on your guests (like Debian 9+), this is what I used to change timezone settings:

config.vm.provision "shell",
    inline: "timedatectl set-timezone Europe/Budapest",
    run: "always" 

This one returns the expected timezone, not the negative value:

# before timedatectl
vagrant@master:~$ timedatectl
               Local time: Fri 2020-07-03 11:52:31 -02
           Universal time: Fri 2020-07-03 13:52:31 UTC
                 RTC time: Fri 2020-07-03 13:52:31
                Time zone: Etc/GMT+2 (-02, -0200)
System clock synchronized: no
              NTP service: inactive
          RTC in local TZ: no

# after timedatectl
vagrant@master:~$ timedatectl
               Local time: Fri 2020-07-03 15:53:24 CEST
           Universal time: Fri 2020-07-03 13:53:24 UTC
                 RTC time: Fri 2020-07-03 13:53:24
                Time zone: Europe/Budapest (CEST, +0200)
System clock synchronized: no
              NTP service: inactive
          RTC in local TZ: no
Lanti
  • 2,299
  • 2
  • 36
  • 69
1

Based on @Benny K.'s answer (https://stackoverflow.com/a/46778032/3194807), with the daylight saving time taken into account:

require "time"
offset = ((Time.zone_offset(Time.now.zone) / 60) / 60) + (Time.now.dst? ? 1 : 0)
timezone_suffix = offset >= 0 ? "-#{offset.to_s}" : "+#{offset.to_s}"
timezone = 'Etc/GMT' + timezone_suffix

tzShellProvision = <<_SHELL_
    ln -fs /usr/share/zoneinfo/#{timezone} /etc/localtime
    dpkg-reconfigure -f noninteractive tzdata
_SHELL_

default.vm.provision :shell, inline: tzShellProvision, run: "always"
0

The way is to set the timezone automatically same like host using the vagrant-timezone plugin.

Install the vagrant-timezone plugin with

vagrant plugin install vagrant-timezone

After that, add the below to your Vagrantfile

config.timezone.value = :host

Note that this functionality has only been tested with an OS X host and Linux guest.

Beowulfdgo
  • 141
  • 1
  • 1
  • 9