En nuestro proyecto C # tenemos la necesidad de representar una fecha sin hora. Sé de la existencia de DateTime, sin embargo, también incorpora una hora del día. Quiero hacer explícito que ciertas variables y argumentos de método se basan en fechas . Por lo tanto, no puedo usar la DateTime.Date
propiedad.
¿Cuáles son los enfoques estándar para este problema? ¿Seguro que no soy el primero en encontrarme con esto? ¿Por qué no hay ninguna Date
clase en C #?
¿Alguien tiene una buena implementación usando una estructura y tal vez algunos métodos de extensión en DateTime y tal vez implementando algunos operadores como == y <,>?
DateTime
crea?Respuestas:
Permítame agregar una actualización a esta pregunta clásica:
La biblioteca Noda Time de Jon Skeet ahora está bastante madura y tiene un tipo de solo fecha llamado
LocalDate
. (Local en este caso solo significa local para alguien , no necesariamente local para la computadora donde se ejecuta el código).Un tipo de solo fecha llamado
Date
es una adición propuesta a .NET Core, a través del proyecto corefxlab . Lo encontrará en elSystem.Time
paquete, junto con unTimeOfDay
tipo y varios métodos de extensión para los tipos existentes.He estudiado este problema de manera significativa, por lo que también compartiré varias razones de la necesidad de estos tipos:
Existe una discrepancia lógica entre un valor de solo fecha y un valor de fecha a la medianoche.
No todos los días locales tienen una medianoche en todas las zonas horarias. Ejemplo: la transición del horario de verano de primavera hacia adelante de Brasil mueve el reloj de 11:59:59 a 01:00:00.
Una fecha y hora siempre se refiere a una hora específica dentro del día, mientras que una fecha solo puede referirse al comienzo del día, al final del día o al rango completo del día.
Adjuntar una hora a una fecha puede hacer que la fecha cambie a medida que el valor se pasa de un entorno a otro, si las zonas horarias no se observan con mucha atención. Esto ocurre comúnmente en JavaScript (cuyo
Date
objeto es realmente una fecha + hora), pero también puede suceder fácilmente en .NET, o en la serialización cuando los datos se pasan entre JavaScript y .NET.Serializar un
DateTime
con XML o JSON (y otros) siempre incluirá la hora, incluso si no es importante. Esto es muy confuso, especialmente considerando cosas como fechas de nacimiento y aniversarios, donde la hora es irrelevante.Arquitectónicamente,
DateTime
es un objeto de valor DDD , pero viola el Principio Único Responsable de varias maneras:Está diseñado como un tipo de fecha + hora, pero a menudo se usa solo como fecha (ignorando la hora) o solo como hora del día (ignorando la fecha). (
TimeSpan
también se usa a menudo para la hora del día, pero ese es otro tema).El
DateTimeKind
valor adjunto a la.Kind
propiedad divide el tipo único en tres. ElUnspecified
tipo es realmente la intención original de la estructura y debe usarse de esa manera. ElUtc
tipo alinea el valor específicamente con UTC y elLocal
tipo alinea el valor con la zona horaria local del entorno.El problema de tener una bandera separada para el tipo es que cada vez que consume un
DateTime
, se supone que debe verificar.Kind
para decidir qué comportamiento tomar. Todos los métodos marco hacen esto, pero otros a menudo lo olvidan. Esta es realmente una violación de SRP, ya que el tipo ahora tiene dos razones diferentes para cambiar (el valor y el tipo).Los dos conducen a usos de API que se compilan, pero a menudo no tienen sentido o tienen casos extremos extraños causados por efectos secundarios. Considerar:
En resumen, si bien a
DateTime
se puede usar solo para una fecha, solo debe hacerlo cuando cada lugar que lo usa tenga mucho cuidado de ignorar la hora, y también tenga mucho cuidado de no intentar convertir hacia y desde UTC u otro zonas horarias.fuente
System.Time.Date
terminara en el marco .NET: /System.Time
como cualquier otro paquete. Todavía no es "oficial".Sospecho que no hay una
Date
clase dedicada pura porque ya tienes laDateTime
que puede manejarla. El tenerDate
conduciría a la duplicación y confusión.Si desea el enfoque estándar, mire la
DateTime.Date
propiedad que proporciona solo la parte de la fecha de aDateTime
con el valor de hora establecido en 12:00:00 medianoche (00:00:00).fuente
Envié un correo electrónico a [email protected] y esa es su respuesta
En mi correo electrónico me pregunté si era porque DateTime usa TimeZoneInfo para obtener la hora de la máquina, en propiedad Now. Entonces yo diría que es porque "las reglas comerciales" están "demasiado acopladas", me lo confirmaron.
fuente
SpaceTime
clase! Oye, según Einstein, el espacio y el tiempo están estrechamente relacionados, por lo que tampoco deberíamos necesitar diferenciarlos, ¿verdad? (!!!!!!!!!!!) Soy un poco nuevo en C #, pero tengo que decir, que es un campo de minas procedentes de VB.NET dónde está, simplemente,date
,Today()
,now
, etc. SinDateTime
prefijo basura, sin curioseaba. (¡Y estos puntos y comas y esta distinción entre mayúsculas y minúsculas es fastidioso! ¡SoloDate
tipo y el resultado debe ser de tipoDate
, si seDate
esperaba el tipo de resultado como cadena sin tiempo. Por ejemplo, Delphi también tiene Date como DateTime, pero typeinfo es diferente para Date y DateTime.Creé un simple estructura de fecha para los momentos en que necesita una fecha simple sin preocuparse por la porción de tiempo, las zonas horarias, local frente a utc, etc.
https://github.com/claycephus/csharp-date
fuente
Si necesita realizar comparaciones de fechas, utilice
Si está mostrando en la pantalla, use
fuente
Permítanme especular: ¿Tal vez se deba a que hasta SQL Server 2008 no había un tipo de datos de fecha en SQL, por lo que sería difícil, así que almacenarlo en el servidor SQL? ¿Y es, después de todo, un producto de Microsoft?
fuente
Quién sabe por qué es así. Hay muchas malas decisiones de diseño en el marco .NET. Sin embargo, creo que esto es bastante menor. Siempre puede ignorar la parte de la hora, por lo que incluso si algún código decide que una DateTime se refiera a algo más que a la fecha, el código que le importa solo debe mirar la parte de la fecha. Alternativamente, puede crear un nuevo tipo que represente solo una fecha y usar funciones en DateTime para hacer el trabajo pesado (cálculos).
fuente
¿Por qué? Solo podemos especular y no ayuda mucho a resolver problemas de ingeniería. Una buena suposición es que
DateTime
contiene toda la funcionalidad que tendría dicha estructura.Si realmente te importa, simplemente envuelve
DateTime
tu propia estructura inmutable que solo expone la fecha (o mira laDateTime.Date
propiedad).fuente
Además de la respuesta de Robert, también tienes el
DateTime.ToShortDateString
método. Además, si realmente desea un objeto Date, siempre puede usar el patrón Adapter y envolver el objeto DateTime exponiendo solo lo que desea (es decir, mes, día, año).fuente
Siempre existe la
DateTime.Date
propiedad que corta la parte de tiempo delDateTime
. Tal vez pueda encapsular o envolver DateTime en su propio tipo de fecha.Y para la pregunta de por qué, bueno, supongo que tendrá que preguntarle a Anders Heljsberg.
fuente
Porque para saber la fecha, debes conocer la hora del sistema (en tics), que incluye la hora, entonces, ¿por qué tirar esa información?
DateTime
tiene unaDate
propiedad si no le importa en absoluto el tiempo.fuente
Sí, también System.DateTime está sellado. He visto a algunas personas jugar con esto creando una clase personalizada solo para obtener el valor de cadena del tiempo como se menciona en publicaciones anteriores, cosas como:
Esto tal vez sea innecesario, ya que podría extraer fácilmente GetShortTimeString de un tipo DateTime antiguo sin una nueva clase
fuente
Si usa las propiedades Fecha o Hoy para obtener solo la parte de la fecha del objeto DateTime.
Entonces obtendrá el componente de fecha solo con el componente de tiempo configurado en medianoche.
fuente