J'ai un serveur en cours d'exécution avec le fuseau horaire défini sur UTC
. Il semblait que c'était généralement une bonne pratique (veuillez me corriger si je me trompe).
Quoi qu'il en soit, l'un des serveurs auxquels je me connecte, afin de scp
fichiers, s'exécute sur EDT
et stocke les fichiers que je dois copier au format /path/to/filename/data20120913
J'ai essayé de rsync
fichiers en utilisant quelque chose comme find's -mtime -1
drapeau pour les fichiers modifiés le dernier jour, mais je n'ai pas eu de chance.
Cela ne me dérange pas d'utiliser simplement scp
pour copier le fichier du jour en cours, mais en ce moment il y a une fenêtre de 4 heures où exécuter date +%Y%m%d
donnera une journée différente sur chaque serveur et cela me dérange un peu.
En regardant à travers man date
Je vois que je peux avoir la sortie de temps en tant que UTC
, mais je ne vois pas de moyen de la faire sortir comme un autre fuseau horaire comme EDT
Je suppose que je pourrais également utiliser quelque chose comme l'extension de date GNU
date -d 20100909 +%s
pour obtenir la date en secondes de l'époque, appliquez un manuel 4 * 60 * 60
deuxième calcul, et voir comment le rendre sous forme de date - mais quand l'heure d'été commencera, ce sera encore une heure de repos.
Existe-t-il un moyen plus simple de sortir la date au format YYYYMMDD
pour EDT
sur un serveur défini sur UTC
?
Vous pouvez définir un fuseau horaire pour la durée de la requête, ainsi:
TZ=America/New_York date
Notez l'espace entre le paramètre TZ
et la commande date
. Dans Bourne-like et rc
- comme Shell, cela définit la variable TZ
uniquement pour la ligne de commande. Dans d'autres shells (csh
, tcsh
, fish
), vous pouvez toujours utiliser la commande env
à la place:
env TZ=America/New_York date
tl; dr
Sur les systèmes Linux. les fuseaux horaires sont définis dans des fichiers dans le /usr/share/zoneinfo
répertoire. Cette structure est souvent appelée "base de données Olson" pour honorer son contributeur fondateur.
Les règles pour chaque fuseau horaire sont définies comme des lignes de fichier texte qui sont ensuite compilées dans un fichier binaire. Les lignes ainsi compilées définissent le nom de la zone; une plage de données et de temps pendant lesquels la zone s'applique; un décalage par rapport à UTC pour l'heure standard; et la notation pour définir comment la transition vers et depuis l'heure d'été se produit, le cas échéant.
Par exemple, le répertoire "America" contient les informations requises pour New York dans le fichier America/New_York
tel qu'utilisé ci-dessus.
Attention, la spécification d'une zone inexistante (nom de fichier) est silencieusement ignorée et les heures UTC sont signalées. Par exemple, cela signale une heure incorrecte:
TZ="America/New York" date ### WRONG ###
La spécification UNIX unique, version 3, connue sous le nom de SUSv3 ou POSIX-2001, note que pour la portabilité, la chaîne de caractères qui identifie la description du fuseau horaire doit commencer par un caractère deux-points. Ainsi, nous pouvons également écrire:
TZ=":America/New_York" date
TZ=":America/Los_Angeles" date
Comme méthode alternative à la spécification des fuseaux horaires en utilisant un chemin d'accès à un fichier de description, SUSv3 décrit le modèle POSIX. Dans ce format, une chaîne est définie comme:
std offset [dst[offset][,start-date[/time],end-date[/time]]]
où std
est le nom du composant standard et dst
est celui de l'heure d'été. Chaque nom se compose de trois caractères ou plus. Le offset
est positif pour les fuseaux horaires à l'ouest du méridien principal et négatif pour ceux à l'est du méridien. Le décalage est ajouté à l'heure locale pour obtenir l'UTC (anciennement GMT). Les champs d'heure start
et end
indiquent quand les transitions standard/lumière du jour se produisent.
Par exemple, dans l'Est des États-Unis, l'heure standard est 5 heures plus tôt que UTC, et nous pouvons spécifier EST5EDT
au lieu de America/New_York
. Cependant, ces alternatives ne sont pas toujours reconnues, en particulier pour les zones en dehors des États-Unis, et il vaut mieux les éviter.
HP-UX (UNIX compatible SUSv3) utilise des règles textuelles dans /usr/lib/tztab
et les noms POSIX comme EST5EDT, CST6CDT, MST7MDT, PST8PDT. Le fichier comprend toutes les règles historiques pour chaque fuseau horaire, semblable à la base de données Olson.
REMARQUE: Vous devriez pouvoir trouver tous les fuseaux horaires en inspectant le répertoire suivant: /usr/share/zoneinfo
.
Vous pouvez le faire en manipulant la variable d'environnement TZ
. Les informations suivantes vous donneront l'heure locale pour les États-Unis/l'Est, qui sera également assez intelligente pour gérer l'heure d'été lorsque cela se produit:
# all on one line
TZ=":US/Eastern" date +%Y%m%d
Le nom de la zone provient des fichiers et répertoires à l'intérieur de /usr/share/zoneinfo
.
Faites attention! La date crachera volontiers l'heure dans votre fuseau horaire actuel, si vous lui donnez un fuseau horaire qu'elle ne reconnaît pas.
Regarde ça:
-bash-4.2$ env TZ=EDT date
Wed Feb 18 19:34:41 EDT 2015
-bash-4.2$ date
Wed Feb 18 19:34:43 UTC 2015
Notez qu'il n'y a pas de fuseau horaire appelé EDT. En réalité,
-bash-4.2$ find /usr/share/zoneinfo -name "*EDT*"
retour
/usr/share/zoneinfo/EST5EDT
/usr/share/zoneinfo/posix/EST5EDT
/usr/share/zoneinfo/right/EST5EDT
Et cela fonctionne:
-bash-4.2$ TZ=EST5EDT date
Wed Feb 18 14:36:59 EST 2015
-bash-4.2$ date
Wed Feb 18 19:37:01 UTC 2015
Cependant, si votre ami vit dans le pays mystique de Gobbledygook et que ses informations de zone coïncident avec les vôtres, vous pouvez avoir la date et l'heure dans la zone de Gobbledygook et il sera heureux de le faire avec une valeur de sortie nulle pour vous faire savoir que le zone ne lui est pas connue:
-bash-4.2$ TZ=Gobbledygook date
Wed Feb 18 19:37:36 Gobbledygook 2015
-bash-4.2$ echo $?
0
TODAY=$(TZ=":US/Eastern" date)
echo $TODAY
La syntaxe date est obscure et sujette aux erreurs, ce qui rend une invocation en ligne de commande difficile. J'ai donc écrit un petit script (je l'ai nommé worldtime), qui imprimera l'heure spécifiée (ou actuelle) à partir du zome de l'heure de base (votre heure locale) dans certains autres fuseaux horaires et l'inverse.
C'est ici. Ajustez-le en fonction de vos besoins, mettez-le sur votre chemin et rendez-le exécutable.
#!/bin/sh # # Imprimer l'heure spécifiée (ou actuelle) à partir de l'heure de base dans d'autres fuseaux horaires # et l'inverse # # Fuseau horaire de base à partir duquel/vers lequel convertir TZBASE = Europe/Athènes # Fuseaux horaires à afficher # Voir/usr/share/zoneinfo/pour plus de noms TZONES = 'UTC America/Los_Angeles America/New_York Europe/London Europe/Paris' # Format d'affichage FORMAT = '% H:% M (% p)% Z% a% m% b% Y' Si ["$ 1"]; puis heure = "$ 1" sinon heure = `date +% T` fi # Affiche l'heure à partir du fuseau horaire d'entrée spécifié dans la sortie spécifiée # fuseau horaire showtime () { TZIN = 1 $ TZOUT = 2 $ TZ = $ TZOUT date --date = 'TZ = "' $ TZIN '"' "$ time" + "$ time $ TZIN est $ TZOUT $ FORMAT" } pour tz en $ TZONES; showtime $ TZBASE $ tz done echo for tz in $ TZONES; faire showtime $ tz $ TZBASE fait
Souvent, vous avez un horodatage dans le fuseau horaire local et vous devez le convertir en tz distant. Cela peut se faire avec:
TZ=America/Curacao date -d 'Tue Nov 28 00:07:05 MSK 2016'
où:
America/Curacao - remote timezone
MSK - local timezone