Comment obtenir l'horodatage Unix en C #

Réponses:

597

Vous obtenez un horodatage Unix en C # en utilisant DateTime.UtcNowet en soustrayant l'heure de l'époque du 01/01/1970.

par exemple

Int32 unixTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;

DateTime.UtcNowpeut être remplacé par n'importe quel DateTimeobjet pour lequel vous souhaitez obtenir l'horodatage unix.

Il y a aussi un champ, DateTime.UnixEpochqui est très mal documenté par MSFT, mais peut se substituer ànew DateTime(1970, 1, 1)

bizzehdee
la source
28
Commentant au nom de @wdhough. "Cette réponse a des limites avec la limite d'Int32 qui est, je crois, 2 147 483 647. Selon onlineconversion.com/unix_time.htm, cela équivaut à une heure du mar., 19 janvier 2038 03:14:07 GMT Je suppose que tout autre type de numéro , double, long, etc. aura finalement une limite aussi, mais je pensais que cela valait la peine d'être mentionné. Je choisis longtemps ici car je voulais un nombre entier. J'espère que cela aide "
IsmailS
11
L'horodatage Unix est traditionnellement un entier 32 bits et a une plage de '1970-01-01 00:00:01' UTC à '2038-01-19 03:14:07' UTC.
the_nuts
89
Fou que la conversion d'heure UNIX ne soit pas dans la bibliothèque standard dans le cadre de DateTime.
2015 à 15h39
7
Ou en utilisant une arythmie entière:DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).Ticks / TimeSpan.TicksPerSecond;
Anton Petrov
2
Le datetime soustrait n'a pas besoin d'être UTC?
jjxtra
573

Depuis .NET 4.6, il y en a DateTimeOffset.ToUnixTimeSeconds().


Il s'agit d'une méthode d'instance, vous devez donc l'appeler sur une instance de DateTimeOffset. Vous pouvez également caster n'importe quelle instance de DateTime, mais méfiez-vous du fuseau horaire .

Pour obtenir l'horodatage actuel:

DateTimeOffset.UtcNow.ToUnixTimeSeconds()

Pour obtenir l'horodatage d'un DateTime:

DateTime foo = DateTime.UtcNow;
long unixTime = ((DateTimeOffset)foo).ToUnixTimeSeconds();
Bob
la source
126
Bien. Il est temps
bizzehdee
35
@MattBorja Heureusement, cela renvoie un Int64- au moment où cela se produit, nous n'utiliserions plus les années terrestres faute de Terre.
Bob
24
Pour tous ceux qui se demandent, vous pouvez obtenir l'horodatage actuel avecDateTimeOffset.Now.ToUnixTimeSeconds()
kR105
8
@bizzehdee, Pun destiné?
st0le
5
Vous pouvez obtenir le Uix unixtimestamp avec: DateTimeOffset.UtcNow.ToUnixTimeSeconds ()
Yair Levi
39

Vous pouvez également utiliser des ticks. Je code pour Windows Mobile, je n'ai donc pas l'ensemble complet de méthodes. TotalSeconds n'est pas disponible pour moi.

long epochTicks = new DateTime(1970, 1, 1).Ticks;
long unixTime = ((DateTime.UtcNow.Ticks - epochTicks) / TimeSpan.TicksPerSecond);

ou

TimeSpan epochTicks = new TimeSpan(new DateTime(1970, 1, 1).Ticks);
TimeSpan unixTicks = new TimeSpan(DateTime.UtcNow.Ticks) - epochTicks;
double unixTime = unixTicks.TotalSeconds;
Dave Hindle
la source
1
Erreur pour la deuxième solution: impossible de convertir le type source «double» en type cible «long».
Pixar
@Pixar: Le deuxième échantillon est corrigé
JBert
5
new DateTime(1970, 1, 1)crée un temps avec une Kindpropriété non spécifiée . Ce que vous voulez vraiment new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)être vraiment correct
désaccordé le
À partir de .NET Core 2.1 Vous pouvez utiliser DateTime.UnixEpoch au lieu du nouveau DateTime (1970, 1, 1) voir docs.microsoft.com/en-us/dotnet/api/…
Jaa H
27

Voici ce que j'utilise:

public long UnixTimeNow()
{
    var timeSpan = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0));
    return (long)timeSpan.TotalSeconds;
}

Gardez à l'esprit que cette méthode renvoie l'heure en temps universel coordonné (UTC).

Bartłomiej Mucha
la source
(TotalSeconds a un doubletype; le lancer trop longtemps entraînera une perte de précision.)
franc
Vous avez raison, mais nous n'avons pas à nous en soucier pendant plusieurs milliers d'années :)
Bartłomiej Mucha
21

La troncature .TotalSecondsest importante car elle est définie commethe value of the current System.TimeSpan structure expressed in whole fractional seconds.

Et que diriez-vous d'une extension pour DateTime? Le second est probablement plus déroutant qu'il vaut jusqu'à ce que les extensions de propriété existent.

/// <summary>
/// Converts a given DateTime into a Unix timestamp
/// </summary>
/// <param name="value">Any DateTime</param>
/// <returns>The given DateTime in Unix timestamp format</returns>
public static int ToUnixTimestamp(this DateTime value)
{
    return (int)Math.Truncate((value.ToUniversalTime().Subtract(new DateTime(1970, 1, 1))).TotalSeconds);
}

/// <summary>
/// Gets a Unix timestamp representing the current moment
/// </summary>
/// <param name="ignored">Parameter ignored</param>
/// <returns>Now expressed as a Unix timestamp</returns>
public static int UnixTimestamp(this DateTime ignored)
{
    return (int)Math.Truncate((DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds);
}
Brad
la source
2
La méthode d'extension est clairement le moyen de le faire proprement. C'est une excellente réponse mûre - et je ne comprends pas pourquoi elle a si peu de votes. Je suis presque sûr que Robba est correct - la conversion de la sortie en (int) tronque automatiquement le résultat. (Ignorant littéralement la partie décimale du double).
Stephanie
4
(ce DateTime ignoré) est très, très trompeur
Lars Corneliussen
6

Lorsque vous soustrayez 1970 de l'heure actuelle, sachez que l'intervalle de temps aura le plus souvent un champ non nul en millisecondes. Si pour une raison quelconque vous êtes intéressé par les millisecondes, gardez cela à l'esprit.

Voici ce que j'ai fait pour contourner ce problème.

 DateTime now = UtcNow();

 // milliseconds Not included.
 DateTime nowToTheSecond = new DateTime(now.Year,now.Month,now.Day,now.Hour,now.Minute,now.Second); 

 TimeSpan span = (date - new DateTime(1970, 1, 1, 0, 0, 0, 0));

 Assert.That(span.Milliseconds, Is.EqualTo(0)); // passes.
Kelly Anderson
la source
5

C'est ce que j'utilise.

 public class TimeStamp
    {
        public Int32 UnixTimeStampUTC()
        {
            Int32 unixTimeStamp;
            DateTime currentTime = DateTime.Now;
            DateTime zuluTime = currentTime.ToUniversalTime();
            DateTime unixEpoch = new DateTime(1970, 1, 1);
            unixTimeStamp = (Int32)(zuluTime.Subtract(unixEpoch)).TotalSeconds;
            return unixTimeStamp;
        }
}
Matthew James Lewis
la source
peut-être en faire une méthode d'extension de DateTime
bizzehdee
3

J'ai épissé les approches les plus élégantes de cette méthode utilitaire:

public static class Ux {
    public static decimal ToUnixTimestampSecs(this DateTime date) => ToUnixTimestampTicks(date) / (decimal) TimeSpan.TicksPerSecond;
    public static long ToUnixTimestampTicks(this DateTime date) => date.ToUniversalTime().Ticks - UnixEpochTicks;
    private static readonly long UnixEpochTicks = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks;
}
XDS
la source
2

Cette solution a aidé dans ma situation:

   public class DateHelper {
     public static double DateTimeToUnixTimestamp(DateTime dateTime)
              {
                    return (TimeZoneInfo.ConvertTimeToUtc(dateTime) -
                             new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc)).TotalSeconds;
              }
    }

en utilisant helper dans le code:

double ret = DateHelper.DateTimeToUnixTimestamp(DateTime.Now)
Aslan Kystaubayev
la source
0

Il existe un ToUnixTimeMilliseconds pour DateTimeOffset dans le système

Vous pouvez écrire une méthode similaire pour DateTime:

public static long ToUnixTimeSeconds(this DateTime value)
{
    return value.Ticks / 10000000L - 62135596800L;
}

10000000L - conversion des ticks en secondes

62135596800L - conversion du 01.01.01 au 01.01.1978

Il n'y a pas de problème avec Utc et les fuites

Timur Lemeshko
la source
0

Voici une classe d'extension à 2 voies qui prend en charge:

  • Localisation du fuseau horaire
  • Entrée \ sortie en secondes ou millisecondes.

Dans le cas d'OP, l'utilisation est:

DateTime.Now.ToUnixtime();

ou

DateTime.UtcNow.ToUnixtime();

Même s'il existe une réponse directe, je pense qu'il est préférable d'utiliser une approche générique. Surtout parce que c'est probablement un projet qui a besoin d'une conversion comme celle-ci, aura également besoin de ces extensions, il est donc préférable d'utiliser le même outil pour tous.

    public static class UnixtimeExtensions
    {
        public static readonly DateTime UNIXTIME_ZERO_POINT = new DateTime(1970, 1, 1, 0, 0,0, DateTimeKind.Utc);

        /// <summary>
        /// Converts a Unix timestamp (UTC timezone by definition) into a DateTime object
        /// </summary>
        /// <param name="value">An input of Unix timestamp in seconds or milliseconds format</param>
        /// <param name="localize">should output be localized or remain in UTC timezone?</param>
        /// <param name="isInMilliseconds">Is input in milliseconds or seconds?</param>
        /// <returns></returns>
        public static DateTime FromUnixtime(this long value, bool localize = false, bool isInMilliseconds = true)
        {
            DateTime result;

            if (isInMilliseconds)
            {
                result = UNIXTIME_ZERO_POINT.AddMilliseconds(value);
            }
            else
            {
                result = UNIXTIME_ZERO_POINT.AddSeconds(value);
            }

            if (localize)
                return result.ToLocalTime();
            else
                return result;
        }

        /// <summary>
        /// Converts a DateTime object into a Unix time stamp
        /// </summary>
        /// <param name="value">any DateTime object as input</param>
        /// <param name="isInMilliseconds">Should output be in milliseconds or seconds?</param>
        /// <returns></returns>
        public static long ToUnixtime(this DateTime value, bool isInMilliseconds = true)
        {
            if (isInMilliseconds)
            {
                return (long)value.ToUniversalTime().Subtract(UNIXTIME_ZERO_POINT).TotalMilliseconds;
            }
            else
            {
                return (long)value.ToUniversalTime().Subtract(UNIXTIME_ZERO_POINT).TotalSeconds;
            }
        }
    }
SingleFlake
la source
Faites attention à ne pas confondre les formats millisecondes et secondes (le meilleur des cas est une exception, le pire est une conversion illogique) J'ai par défaut l'entrée \ sortie au format millisecondes. Si vous préférez utiliser le format des secondes par défaut, passez simplement isInMilliseconds = true (dans les deux méthodes) sur false.
SingleFlake
0

Je l'ai utilisé après avoir lutté pendant un certain temps, il répond également au décalage du fuseau horaire:

    public double Convert_DatTime_To_UNIXDATETIME(DateTime dt)
    {
        System.DateTime from_date = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
        double unix_time_since = dt.Subtract(from_date).TotalMilliseconds;

        TimeSpan ts_offset = TimeZoneInfo.Local.GetUtcOffset(DateTime.UtcNow);

        double offset = ts_offset.TotalMilliseconds;

        return unix_time_since - offset;
    }
Bruce Cameron
la source
-1

Le code simple que j'utilise:

public static long CurrentTimestamp()
{
   return (long)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds * 1000);
}

Ce code donne l'horodatage Unix, millisecondes totales du 1970-01-01 à maintenant.

Erkin Eren
la source