poner definicion create borde java calendar

definicion - set border java



¿Por qué es el mes de enero 0 en el calendario de Java? (16)

En java.util.Calendar , enero se define como el mes 0, no el mes 1. ¿Hay alguna razón específica para eso?

He visto a mucha gente confundirse sobre eso ...


tl; dr

Month.FEBRUARY.getValue() // February → 2.

2

Detalles

La respuesta de Jon Skeet es correcta.

Ahora tenemos un reemplazo moderno para esas antiguas y problemáticas clases de fecha y hora: las clases java.time .

java.time.Month

Entre esas clases está el Month enum . Una enumeración transporta uno o más objetos predefinidos, objetos que se crean automáticamente cuando se carga la clase. En Month tenemos una docena de objetos de este tipo, cada uno con un nombre: JANUARY , FEBRUARY , MARCH , y así sucesivamente. Cada uno de ellos es una constante de clase static final public . Puedes usar y pasar estos objetos a cualquier parte de tu código. Ejemplo: someMethod( Month.AUGUST )

Afortunadamente, tienen una numeración sana, 1-12, donde 1 es enero y 12 es diciembre.

Obtenga un objeto de Month para un número de mes en particular (1-12).

Month month = Month.of( 2 ); // 2 → February.

Yendo en la otra dirección, pida a un objeto Month su número de mes.

int monthNumber = Month.FEBRUARY.getValue(); // February → 2.

Muchos otros métodos prácticos en esta clase, como saber la cantidad de días en cada mes . La clase puede incluso generar un nombre localizado del mes.

Puede obtener el nombre localizado del mes, en varias longitudes o abreviaturas.

String output = Month.FEBRUARY.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH );

Février

Además, debe pasar los objetos de esta enumeración alrededor de su base de código en lugar de simples números enteros . Al hacerlo, proporciona seguridad de tipos, garantiza un rango de valores válido y hace que su código se autodocumente. Consulte el Tutorial de Oracle si no está familiarizado con la instalación de enumeración sorprendentemente poderosa en Java.

También puede encontrar útiles las clases Year and YearMonth .

Acerca de java.time

El marco java.time está integrado en Java 8 y java.time posteriores. Estas clases sustituyen a las antiguas y problemáticas clases de fecha y hora como java.util.Date , .Calendar , & java.text.SimpleDateFormat .

El proyecto Joda-Time , ahora en modo de mantenimiento , aconseja la migración a java.time.

Para obtener más información, consulte el Tutorial de Oracle . Y busca para muchos ejemplos y explicaciones. La especificación es JSR 310 .

¿Dónde obtener las clases java.time?

  • Java SE 8 y SE 9 y posteriores
    • Incorporado.
    • Parte de la API de Java estándar con una implementación en paquete.
    • Java 9 agrega algunas características menores y correcciones.
  • Java SE 6 y SE 7
    • Gran parte de la funcionalidad de java.time está respaldada a Java 6 y 7 en ThreeTen-Backport .
  • Android
    • El proyecto ThreeTenABP adapta ThreeTen-Backport (mencionado anteriormente) para Android específicamente.
    • Ver cómo usar ...

El proyecto ThreeTen-Extra extiende java.time con clases adicionales. Este proyecto es un terreno de prueba para posibles adiciones futuras a java.time. Puede encontrar algunas clases útiles aquí como Interval , YearWeek , YearQuarter , y more .


java.util.Month

Java le proporciona otra forma de utilizar índices basados ​​en 1 durante meses. Utilice la enumeración java.time.Month . Un objeto está predefinido para cada uno de los doce meses. Tienen números asignados a cada 1-12 para enero-diciembre; llame a getValue para obtener el número.

Utilice Month.JULY (le da 7) en lugar de Calendar.JULY (le da 6).

(import java.time.*;)


Además de la respuesta de flojedad de DannySmurf, agregaré que es para animarle a usar las constantes, como Calendar.JANUARY .


En Java 8, hay una nueva API de fecha / hora JSR 310 que es más sana. El líder de especificaciones es el mismo que el autor principal de JodaTime y comparten muchos conceptos y patrones similares.


Es solo una parte del terrible desorden que es la API de fecha / hora de Java. Enumerar lo que está mal llevaría mucho tiempo (y estoy seguro de que no conozco la mitad de los problemas). Es cierto que trabajar con fechas y horas es complicado, pero aaargh de todos modos.

Hazte un favor y usa Joda Time en su lugar, o posiblemente JSR-310 .

EDITAR: En cuanto a las razones por las que, como se señaló en otras respuestas, podría deberse a las API C antiguas, o simplemente a una sensación general de comenzar todo desde 0 ... excepto que los días comienzan con 1, por supuesto. Dudo que alguien fuera del equipo de implementación original pudiera realmente dar razones, pero una vez más, insto a los lectores a que no se preocupen tanto por la razón por la que se tomaron las malas decisiones, como para ver toda la gama de maldad en java.util.Calendar y encontrar algo mejor

Un punto a favor del uso de índices basados ​​en 0 es que hace que las cosas como "matrices de nombres" sean más fáciles:

// I "know" there are 12 months String[] monthNames = new String[12]; // and populate... String name = monthNames[calendar.get(Calendar.MONTH)];

Por supuesto, esto falla tan pronto como obtiene un calendario con 13 meses ... pero al menos el tamaño especificado es la cantidad de meses que espera.

Esto no es una buena razón, pero es una razón ...

EDITAR: Como una especie de comentario, solicita algunas ideas sobre lo que creo que está mal con la fecha / calendario:

  • Bases sorprendentes (1900 como base de año en Date, es cierto que para constructores en desuso; 0 como base de mes en ambas)
  • Mutabilidad: el uso de tipos inmutables hace que sea mucho más sencillo trabajar con valores realmente efectivos.
  • Un conjunto de tipos insuficiente: es bueno tener la Date y el Calendar como cosas diferentes, pero falta la separación de los valores "locales" frente a "zonificados", al igual que la fecha / hora frente a la fecha frente a la hora
  • Una API que conduce a un código feo con constantes mágicas, en lugar de métodos claramente nombrados
  • Una API que es muy difícil de razonar: todo el asunto sobre cuándo se vuelven a calcular las cosas, etc.
  • El uso de constructores sin parámetros para predeterminar "ahora", lo que lleva a un código difícil de probar
  • La implementación Date.toString() que siempre usa la zona horaria local del sistema (eso confunde a muchos usuarios de Desbordamiento de Pila antes de ahora)

Ha habido muchas respuestas a esto, pero daré mi opinión sobre el tema de todos modos. La razón detrás de este extraño comportamiento, como se indicó anteriormente, proviene de POSIX C time.h donde los meses se almacenaron en un int con el rango de 0-11. Para explicar por qué, miradlo así; Los años y los días se consideran números en el lenguaje hablado, pero los meses tienen sus propios nombres. Por lo tanto, como enero es el primer mes, se almacenará como desplazamiento 0, el primer elemento de la matriz. monthname[JANUARY] sería "January" . El primer mes del año es el primer elemento de la matriz del mes.

Por otro lado, los números de los días, ya que no tienen nombres, almacenarlos en un int como 0-30 sería confuso, agregaría muchas instrucciones al day+1 para la salida y, por supuesto, sería propenso a muchos errores.

Dicho esto, la incoherencia es confusa, especialmente en javascript (que también ha heredado esta "característica"), un lenguaje de scripting en el que esto se debe abstraer lejos de langague.

TL; DR : Porque los meses tienen nombres y los días del mes no.


Los lenguajes basados ​​en C copian C hasta cierto punto. La estructura tm (definida en time.h ) tiene un campo entero tm_mon con el rango (comentado) de 0-11.

Los lenguajes basados ​​en C inician matrices en el índice 0. Así que esto fue conveniente para generar una cadena en una matriz de nombres de mes, con tm_mon como el índice.


No se define exactamente como cero per se, se define como Calendario. Enero. Es el problema de usar ints como constantes en lugar de enumeraciones. Calendar.January == 0.


Para mí, nadie lo explica mejor que mindpro.com :

Gotchas

java.util.GregorianCalendar tiene muchos menos errores y errores que la old java.util.Date clase old java.util.Date pero aún no es un día de campo.

Si hubiera habido programadores cuando se propuso por primera vez el horario de verano, lo habrían vetado como insano e intratable. Con el horario de verano, existe una ambigüedad fundamental. En el otoño, cuando se retrasan los relojes una hora a las 2 AM, hay dos instantes diferentes en el tiempo, ambos llamados 1:30 AM hora local. Puede diferenciarlos solo si registra si planeaba el horario de verano o la hora estándar con la lectura.

Desafortunadamente, no hay manera de decirle a GregorianCalendar cuál fue su intención. Debe recurrir a decir la hora local con la zona horaria UTC ficticia para evitar la ambigüedad. Los programadores generalmente cierran sus ojos a este problema y solo esperan que nadie haga nada durante esta hora.

Error del milenio. Los errores aún no están fuera de las clases de Calendario. Incluso en JDK (Java Development Kit) 1.3 hay un error de 2001. Considere el siguiente código:

GregorianCalendar gc = new GregorianCalendar(); gc.setLenient( false ); /* Bug only manifests if lenient set false */ gc.set( 2001, 1, 1, 1, 0, 0 ); int year = gc.get ( Calendar.YEAR ); /* throws exception */

El error desaparece a las 7AM en 2001/01/01 para MST.

GregorianCalendar está controlado por un gigante de pila de constantes mágicas int sin tipo. Esta técnica destruye totalmente cualquier esperanza de verificación de errores en tiempo de compilación. Por ejemplo, para obtener el mes que usa GregorianCalendar. get(Calendar.MONTH)); GregorianCalendar. get(Calendar.MONTH));

GregorianCalendar tiene el GregorianCalendar.get(Calendar.ZONE_OFFSET) procesar GregorianCalendar.get(Calendar.ZONE_OFFSET) y el horario de verano GregorianCalendar. get( Calendar. DST_OFFSET) GregorianCalendar. get( Calendar. DST_OFFSET) , pero no hay manera de obtener el desplazamiento de zona horaria real que se está utilizando. Debes obtener estos dos por separado y sumarlos.

GregorianCalendar.set( year, month, day, hour, minute) no establece los segundos en 0.

DateFormat y GregorianCalendar no se DateFormat correctamente. Debe especificar el calendario dos veces, una vez indirectamente como una fecha.

Si el usuario no ha configurado su zona horaria correctamente, se establecerá de forma predeterminada en PST o GMT.

En GregorianCalendar, los meses se numeran a partir de enero = 0, en lugar de 1 como lo hacen todos los demás en el planeta. Sin embargo, los días comienzan en 1, al igual que los días de la semana con domingo = 1, lunes = 2, ... sábado = 7. Sin embargo, DateFormat. parse se comporta de forma tradicional con enero = 1.


Personalmente, tomé la extrañeza de la API de calendario de Java como una indicación de que necesitaba divorciarme de la mentalidad centrada en el gregoriano y tratar de programar de manera más agnóstica a ese respecto. Específicamente, aprendí una vez más a evitar constantes codificadas para cosas como meses.

¿Cuál de los siguientes es más probable que sea correcto?

if (date.getMonth() == 3) out.print("March"); if (date.getMonth() == Calendar.MARCH) out.print("March");

Esto ilustra una cosa que me molesta un poco sobre Joda Time: puede animar a los programadores a pensar en términos de constantes codificadas. (Sin embargo, solo un poco. No es como si Joda estuviera obligando a los programadores a programar mal).


Porque hacer matemáticas con meses es mucho más fácil.

1 mes después de diciembre es enero, pero para resolverlo, normalmente tendría que tomar el número del mes y hacer matemáticas

12 + 1 = 13 // What month is 13?

¡Lo sé! Puedo arreglar esto rápidamente usando un módulo de 12.

(12 + 1) % 12 = 1

Esto funciona bien durante 11 meses hasta noviembre ...

(11 + 1) % 12 = 0 // What month is 0?

Puede hacer que todo este trabajo vuelva a restar 1 antes de sumar el mes, luego hacer su módulo y finalmente agregar 1 nuevamente ... también conocido como trabajo alrededor de un problema subyacente.

((11 - 1 + 1) % 12) + 1 = 12 // Lots of magical numbers!

Ahora pensemos en el problema con los meses 0 - 11.

(0 + 1) % 12 = 1 // February (1 + 1) % 12 = 2 // March (2 + 1) % 12 = 3 // April (3 + 1) % 12 = 4 // May (4 + 1) % 12 = 5 // June (5 + 1) % 12 = 6 // July (6 + 1) % 12 = 7 // August (7 + 1) % 12 = 8 // September (8 + 1) % 12 = 9 // October (9 + 1) % 12 = 10 // November (10 + 1) % 12 = 11 // December (11 + 1) % 12 = 0 // January

Todos los meses funcionan igual y no es necesario trabajar alrededor.


Porque la escritura del lenguaje es más difícil de lo que parece, y manejar el tiempo en particular es mucho más difícil de lo que la mayoría de la gente piensa. Para una pequeña parte del problema (en realidad, no de Java), vea el video de YouTube "El problema con las zonas horarias y los horarios" en https://www.youtube.com/watch?v=-5wpm-gesOY . No se sorprenda si su cabeza se cae de la risa confundida.


Porque los programadores están obsesionados con los índices basados ​​en 0. Está bien, es un poco más complicado que eso: tiene más sentido cuando trabajas con lógica de nivel inferior para usar la indexación basada en 0. Pero en general, todavía me quedo con mi primera frase.


Porque todo comienza con 0. Este es un hecho básico de la programación en Java. Si una cosa fuera a desviarse de eso, entonces eso llevaría a toda una confusión de confusión. No discutamos la formación de ellos y codifiquemos con ellos.


Probablemente porque la "estructura tm" de C hace lo mismo.


Yo diría la pereza. Las matrices comienzan en 0 (todo el mundo sabe eso); Los meses del año son una serie, lo que me lleva a creer que algún ingeniero de Sun no se molestó en poner este pequeño detalle en el código de Java.