non mi sono soffermato a spiegare quel che fa quel codice...
allora innanzitutto, non c'è una vera ragione per cui ho scritto un metodo che ritorna uno JSpinner se non per pigrizia (avevo già una classe test con l'ossatura di quel metodo).
Venendo alla ciccia:
il new Date(0) l'ho derivato da una piccola ricerchina: apparentemente c'è qualche problema nella gestione di SpinnerDateModel (si incasina nelle gestione delle date in assenza di anno per via della gestione interna che apparentemente è legata ad Epoch, proprio in assenza di anno), comunque trattandosi di un JSpinner che giochicchia con ore e minuti ci è di poco interesse
- Creo il mio JSpinner attaccandogli come modello un'istanza di una mia versione di SpinnerDateModel.
Venendo alla classe privata che estende SpinnerDateModel: i metodi che ci interessano sono quelli che generano gli scatti successivo e precedente, ovvero quello che avviene alla pressione delle freccette di modifica.
Il doppio calendario lo uso solo per pigrizia: uno (tempCal) è libero di essere modificato come gli pare, l'altro (cal) che invece rispecchia l'orario del JSpinner e che quindi deve sottostare ai vincoli imposti, viene modificato solo se la modifica (testata su tempCal) ricade nell'intervallo di validità.
Nel tuo caso specifico, si sarebbe anche potuto omettere "field" ed esplicitarlo in Calendar.MINUTE, ma se domani volessi riutilizzare il tutto incrementando le ore a 2 a 2, ti basterà modificare meno codice... anzi portando il 15 a non essere hard-coded, ovvero inserendolo in una variabile "incremento", ti basterebbe modificare una sola riga.