Run at 11:59 PM on December 31st | CronBase
59 23 31 12 * One minute before midnight on the final day of December every year.
This cron expression schedules a task to execute precisely at eleven fifty-nine PM on December thirty-first annually. It is widely used in production environments to perform critical year-end operations, final financial ledger closings, database archiving, and system state resets immediately before the calendar year transitions.
- Minute
- 59
- Hour
- 23
- Day of Month
- 31
- Month
- 12
- Day of Week
- *
Next 5 Runs
- in 159d 3h
- in 524d 3h
- in 890d 3h
- in 1255d 3h
- in 1620d 3h
* Tools
Code & Implementations
#!/usr/bin/env bash
# Production-ready crontab installation script for year-end tasks
set -euo pipefail
CRON_EXPRESSION="59 23 31 12 *"
JOB_COMMAND="/usr/local/bin/year-end-cleanup.sh >> /var/log/cron-year-end.log 2>&1"
if [ ! -x "/usr/local/bin/year-end-cleanup.sh" ]; then
echo "Error: Executable script /usr/local/bin/year-end-cleanup.sh not found." >&2
exit 1
fi
(crontab -l 2>/dev/null | grep -v -F "$JOB_COMMAND"; echo "$CRON_EXPRESSION $JOB_COMMAND") | crontab -
echo "Successfully scheduled year-end job." › Setup notes
Save this script as setup-cron.sh, make it executable with chmod +x, and run it as root or the application user to install the year-end cron job safely.
const cron = require('node-cron');
const { exec } = require('child_process');
// Schedule task for 23:59 on December 31st
const task = cron.schedule('59 23 31 12 *', () => {
console.log('[INFO] Starting annual year-end archival process...');
exec('/usr/local/bin/archive-fiscal-year.sh', (error, stdout, stderr) => {
if (error) {
console.error(`[ERROR] Year-end process failed: ${error.message}`);
return;
}
if (stderr) {
console.warn(`[WARNING] Process stderr: ${stderr}`);
}
console.log(`[SUCCESS] Year-end process completed: ${stdout}`);
});
}, {
scheduled: true,
timezone: "UTC"
}); › Setup notes
Install node-cron using npm install node-cron. Run this Node.js process using a process manager like PM2 to ensure it remains running continuously throughout the year.
import logging
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.triggers.cron import CronTrigger
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger('YearEndScheduler')
def run_year_end_job():
logger.info("Initiating annual year-end financial consolidation...")
try:
# Place your business logic here
logger.info("Annual consolidation successfully completed.")
except Exception as e:
logger.error(f"Critical failure during year-end run: {str(e)}", exc_info=True)
scheduler = BlockingScheduler()
trigger = CronTrigger(month=12, day=31, hour=23, minute=59, timezone='UTC')
scheduler.add_job(run_year_end_job, trigger, id='year_end_cleanup')
try:
logger.info("Starting scheduler for year-end task...")
scheduler.start()
except (KeyboardInterrupt, SystemExit):
logger.info("Scheduler stopped manually.") › Setup notes
Install the required dependency with pip install apscheduler, then run this script as a daemon or systemd service to ensure persistent year-round monitoring.
package main
import (
"log"
"os"
"os/signal"
"syscall"
"time"
"github.com/robfig/cron/v3"
)
func main() {
logger := log.New(os.Stdout, "[YearEndJob] ", log.LstdFlags|log.Lshortfile)
nyc, err := time.LoadLocation("UTC")
if err != nil {
logger.Fatalf("Failed to load timezone: %v", err)
}
c := cron.New(cron.WithLocation(nyc))
_, err = c.AddFunc("59 23 31 12 *", func() {
logger.Println("Starting annual database partition rotation...")
// Execute migration logic here
logger.Println("Database partition rotation completed successfully.")
})
if err != nil {
logger.Fatalf("Failed to schedule job: %v", err)
}
c.Start()
logger.Println("Scheduler started successfully.")
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
<-sigChan
logger.Println("Shutting down scheduler...")
c.Stop()
} › Setup notes
Initialize your Go module, run go get github.com/robfig/cron/v3, and build the binary. Run the compiled binary in an environment with access to the system's timezone database.
package com.example.cron;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class YearEndScheduler {
private static final Logger logger = LoggerFactory.getLogger(YearEndScheduler.class);
@Scheduled(cron = "0 59 23 31 12 *", zone = "UTC")
public void executeYearEndProcess() {
logger.info("Starting annual fiscal year-end batch processing...");
try {
// Execute business logic here
logger.info("Fiscal year-end batch processing finished successfully.");
} catch (Exception e) {
logger.error("Critical error during year-end execution: ", e);
}
}
} › Setup notes
Ensure @EnableScheduling is declared on your Spring Boot application class. This task uses Spring's 6-field cron format, which prepends seconds to the standard schedule.
apiVersion: batch/v1
kind: CronJob
metadata:
name: year-end-reconciliation
namespace: production
spec:
schedule: "59 23 31 12 *"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 5
jobTemplate:
spec:
template:
spec:
containers:
- name: reconciler
image: registry.company.com/finance/reconciler:v2.1.0
env:
- name: ENVIRONMENT
value: "production"
resources:
limits:
cpu: "1"
memory: "2Gi"
requests:
cpu: "500m"
memory: "1Gi"
restartPolicy: OnFailure › Setup notes
Apply this manifest to your cluster using kubectl apply -f cronjob.yaml. Ensure your Kubernetes cluster control plane is synchronized with NTP to guarantee correct timing.
Last verified:
Keep this cron job monitored 24/7
UptimeRobot alerts you the moment a scheduled job stops responding. Free plan monitors up to 50 endpoints — no credit card required.
Platform Equivalents
AWS EventBridge
Standard cron expressions often need conversion for AWS EventBridge schedules.
cron(59 23 31 12 ? *) Systemd Timer
OnCalendar*-12-31 23:59:00
[Unit]
Description=Timer for cron expression: 59 23 31 12 *
[Timer]
OnCalendar=*-12-31 23:59:00
Persistent=true
[Install]
WantedBy=timers.target
Last verified:
Frequently Asked Questions
What timezone does this cron expression run in?
By default, standard cron runs in the system's local timezone. It is highly recommended to configure your cron daemon or application runtime to use UTC to avoid issues with Daylight Saving Time shifts and server migrations.
How can I test a job that only runs once a year?
You can test the job by executing the underlying script manually in a staging environment, or by temporarily changing the cron expression to a near-future time (e.g., five minutes from now) to verify the end-to-end execution flow.
What happens if the server is offline at 11:59 PM on December 31st?
Standard cron will completely miss the execution. If your system was offline, the task will not run until the following year. To prevent this, use tools like Anacron, or design your job with monitoring that alerts on missed execution heartbeats.
Can I use this schedule to rotate log files?
While you can, using this schedule for log rotation is usually inefficient. Log rotation should happen much more frequently (daily or weekly) or based on file size. This schedule is better reserved for annual fiscal reports or year-end database partitioning.
How should I handle failures for a job that runs so infrequently?
Implement a robust dead-man's switch or external monitoring tool (like Healthchecks.io or Prometheus Pushgateway). If the job fails or does not report success by 00:15 AM on January 1st, it should trigger high-priority alerts to your on-call engineering team.
* Explore
Related expressions you might need
Last verified: