C # DateTime: O que “data” para usar quando eu estou usando apenas o “tempo”?

Eu estou usando um DateTime em C # para exibir os horários. Qual porção de data todos usam ao construir um horário?

por exemplo, o seguinte não é válido:

//4:37:58 PM DateTime time = new DateTime(0, 0, 0, 16, 47, 58); 

porque não há zero-th mês ou zero-th dia.

Eu uso a data zero do COM?

 //4:37:58 PM DateTime time = new DateTime(1899, 12, 30, 16, 47, 58); 

Ou talvez o SQL Server?

 //4:37:58 PM DateTime time = new DateTime(1900, 1, 1, 16, 47, 58); 

Eu percebo que é arbitrário, já que eu vou estar ignorando as porções de data no código, mas ainda seria bom poder usar:

 DateTime duration = time2 - time1; 

Responda

acho que gosto do MinValue

  DateTime time = DateTime.MinValue.Date.Add(new TimeSpan(16, 47, 58)); 

Nota: eu não posso usar um TimeSpan, porque isso não armazena as horas do dia. E a razão pela qual eu sei é porque não há maneira de exibir seu conteúdo como um tempo.

O que significa que o TimeSpan registra um período de tempo , não uma hora do dia . por exemplo

 TimeSpan t = new TimeSpan(16, 47, 58); t.ToString(); 

retorna um intervalo de tempo no formato horas : minutos : segundos , por exemplo:

 16:47:58 

em vez de um tempo:

 4:47:58 PM (United States) 04:47:58 nm (South Africa) 4:47:58.MD (Albania) 16:47:58 (Algeria) 04:47:58 م (Bahrain) PM 4:47:58 (Singapore)下午 04:47:58 (Taiwan) 04:47:58 PM (Belize) 4:47:58 pm (New Zealand) 4:47:58 μμ (Greece) 16.47.58 (Italy) 오후 4:47:58 (Korea) 04:47:58 ب.ظ (Iran) ਸ਼ਾਮ 04:47:58 (India) 04:47:58 pm (Argentina) etc 

Em outras palavras, há uma diferença entre um período de tempo e um tempo. E também perceba que o TimeSpan não fornece um mecanismo para converter um período de tempo em uma hora do dia – e há uma razão para isso.

e quanto a DateTime.MinValue?

Vamos ajudar os caras que querem uma estrutura de tempo:

 ///  /// Time structure ///  public struct Time : IComparable { private int minuteOfDay; public static Time Midnight = "0:00"; private static int MIN_OF_DAY = 60 * 24; public Time(int minuteOfDay) { if (minuteOfDay >= (60 * 24) || minuteOfDay < 0) throw new ArgumentException("Must be in the range 0-1439", "minuteOfDay"); this.minuteOfDay = minuteOfDay; } public Time(int hour, int minutes) { if (hour < 0 || hour > 23) throw new ArgumentException("Must be in the range 0-23", "hour"); if (minutes < 0 || minutes > 59) throw new ArgumentException("Must be in the range 0-59", "minutes"); minuteOfDay = (hour * 60) + minutes; } #region Operators public static implicit operator Time(string s) { var parts = s.Split(':'); if (parts.Length != 2) throw new ArgumentException("Time must be specified on the form tt:mm"); return new Time(int.Parse(parts[0]), int.Parse(parts[1])); } public static bool operator >(Time t1, Time t2) { return t1.MinuteOfDay > t2.MinuteOfDay; } public static bool operator < (Time t1, Time t2) { return t1.MinuteOfDay < t2.MinuteOfDay; } public static bool operator >=(Time t1, Time t2) { return t1.MinuteOfDay >= t2.MinuteOfDay; } public static bool operator < =(Time t1, Time t2) { return t1.MinuteOfDay <= t2.MinuteOfDay; } public static bool operator ==(Time t1, Time t2) { return t1.GetHashCode() == t2.GetHashCode(); } public static bool operator !=(Time t1, Time t2) { return t1.GetHashCode() != t2.GetHashCode(); } /// Time /// Minutes that remain to /// Time conferred minutes public static Time operator +(Time t, int min) { if (t.minuteOfDay + min < (24 * 60)) { t.minuteOfDay += min; return t; } else { t.minuteOfDay = (t.minuteOfDay + min) % MIN_OF_DAY; return t; } } public static Time operator -(Time t, int min) { if (t.minuteOfDay - min > -1) { t.minuteOfDay -= min; return t; } else { t.minuteOfDay = MIN_OF_DAY + (t.minuteOfDay - min); return t; } } public static TimeSpan operator -(Time t1, Time t2) { return TimeSpan.FromMinutes(Time.Span(t2, t1)); } #endregion public int Hour { get { return (int)(minuteOfDay / 60); } } public int Minutes { get { return minuteOfDay % 60; } } public int MinuteOfDay { get { return minuteOfDay; } } public Time AddHours(int hours) { return this + (hours * 60); } public int CompareTo(Time other) { return this.minuteOfDay.CompareTo(other.minuteOfDay); } #region Overrides public override int GetHashCode() { return minuteOfDay.GetHashCode(); } public override string ToString() { return string.Format("{0}:{1:00}", Hour, Minutes); } #endregion /// /// Safe enumerering - whatever interval applied max days /// /// Start time /// Spring in minutes /// public static IEnumerable Range(Time start, int step) { return Range(start, start, step); } /// /// Safe enumeration - whatever interval applied max days /// public static IEnumerable Range(Time start, Time stop, int step) { int offset = start.MinuteOfDay; for (var i = 0; i < Time.Span(start, stop); i += step) { yield return Time.Midnight + (i + offset); } } /// /// Calculates the number of minutes between t1 and t2 /// public static int Span(Time t1, Time t2) { if (t1 < t2) // same day return t2.MinuteOfDay - t1.MinuteOfDay; else // over midnight return MIN_OF_DAY - t1.MinuteOfDay + t2.MinuteOfDay; } } 

Um TimeSpan certamente pode armazenar a hora do dia – você só precisa tratar o valor como a quantidade de tempo decorrido desde a meia-noite, basicamente da mesma forma que lemos um relógio.

Pessoalmente, eu criaria uma struct Time personalizada que contivesse uma instância de DateTime , e que tivesse propriedades, construtores, etc., mas não exponha dias / meses / etc. Basta fazer com que todos os seus accessres públicos passem para a instância contida. Em seguida, você pode simplesmente ter a época como um campo private static readonly DateTime e não importa qual valor você escolhe, pois tudo está bem contido em sua estrutura personalizada. No resto do seu código pode simplesmente escrever:

 var time = new Time(16, 47, 58); 

Dado que DateTime.TimeOfDay retorna um TimeSpan, eu usaria isso.

Por que você não pode usar um TimeSpan? Não entendo o seu comentário que não armazena horas do dia.

Para exibir um TimeSpan formatado com cultura local, basta adicioná-lo a uma data como DateTime.Today. Algo assim:

(DateTime.Today + timeSpan) .ToString ();

Como seu valor realmente não representa uma data, é melhor armazená-lo como TimeSpan até que seja exibido.

Como sobre DateTime.Now.TimeOfDay e use o TimeSpan ?

Re “porque isso não armazena as horas do dia.” – Bem, isso acontece se você pensar em um TimeSpan como o tempo desde a meia-noite.

Uma “duração”, por exemplo, grita TimeSpan .

Eu recomendo DateTime.MinValue

Você pode simplesmente criar um novo DateTime com um literal de string.

String literal para o tempo:

 DateTime t = new DateTime("01:00:30"); 

String literal para data:

 DateTime t = new DateTime("01/05/2008"); // english format DateTime t = new DateTime("05.01.2008"); // german format 

Para um DateTime com valores de data e hora:

 DateTime t = new DateTime("01/05/2008T01:00:30"); 

Na maioria dos casos, ao criar um DateTime, eu o defino como DateTime.Now, se ele não estiver definido para mais nada. Se você instanciar um DateTime manualmente, você deve tomar cuidado com o conjunto DateTimeKind corretamente, caso contrário isso pode levar a surpresas.

Posso sugerir que, em alguns casos, uma struct customizada poderia funcionar? Ele poderia ter um valor de apoio Int32 (há 86 milhões de milissegundos em um dia; isso caberia em um Int32).

Pode haver propriedades somente get:

Horas Minutos Segundos Milissegundos

Você também pode sobrecarregar operadores como +, – e assim por diante. Implemente IEquatable, IComparable e qualquer que seja o caso. Sobrecarga é igual a ==. Sobrecarregar e replace ToString.

Você também pode fornecer mais methods para construir a partir de um DateTime ou append a um datetime e assim por diante.

Use um TimeSpan e torne-o UTC se você tiver problemas de fuso horário.

Não há muita diferença em comparação com a resposta aceita. Apenas para implementar a ideia.

 public class TimeOfDay { public DateTime time; public TimeOfDay(int Hour, int Minute, int Second) { time = DateTime.MinValue.Date.Add(new TimeSpan(Hour, Minute, Second)); } }