πTime Duration Calculator
Calculate exact time duration between two dates and times. Perfect for work hours, project tracking, event planning, and time management. Supports AM/PM, 24-hour format, and multiple time zones.
π€ What Is a Time Duration Calculator?
Think of a stopwatch that measures any period in history - that's a time duration calculator! It precisely calculates the exact time between any two dates and times, perfect for tracking work hours, planning projects, counting down to events, or calculating your exact age.
:
:
β° Enter your start and end times above to calculate the duration
β‘ Quick Examples
π Standard Work Day
9:00 AM - 5:30 PM (8.5 hours)
πΌ Meeting Duration
2:15 PM - 3:45 PM (1.5 hours)
βοΈ Flight Time
11:30 PM - 7:45 AM (+1 day)
π Project Timeline
Jan 1 - Mar 15 (74 days)
π Night Shift
10:00 PM - 6:00 AM (8 hours)
β Break Time
12:00 PM - 1:00 PM (1 hour)
${mainDisplay}
${formatDetailedDuration(result)}
Total Hours
${formatDecimal(result.totalHours)}
Decimal format
Total Minutes
${formatNumber(result.totalMinutes)}
In minutes
Total Seconds
${formatNumber(result.totalSeconds)}
In seconds
Calendar Days
${result.days}
Days included
β° Enter your start and end times above to calculate the duration
`;
}
// ========== UTILITY FUNCTIONS ==========
// Format numbers with commas
function formatNumber(num) {
return new Intl.NumberFormat('en-US').format(Math.round(num));
}
// Format decimal numbers
function formatDecimal(num) {
return new Intl.NumberFormat('en-US', {
minimumFractionDigits: 0,
maximumFractionDigits: 2
}).format(num);
}
// Copy to clipboard
function copyToClipboard(text) {
navigator.clipboard.writeText(text).then(() => {
showNotification('Results copied to clipboard!', 'success');
}).catch(() => {
// Fallback for older browsers
const textArea = document.createElement('textarea');
textArea.value = text;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('copy');
document.body.removeChild(textArea);
showNotification('Results copied to clipboard!', 'success');
});
}
// Show error
function showError(elementId, message) {
const errorElement = document.getElementById(elementId);
if (errorElement) {
errorElement.textContent = message;
}
}
// Clear errors
function clearErrors() {
document.querySelectorAll('.error').forEach(el => el.textContent = '');
}
// Show notification toast
function showNotification(message, type = 'success') {
const toast = document.createElement('div');
toast.className = `toast ${type}`;
toast.textContent = message;
document.body.appendChild(toast);
setTimeout(() => {
toast.remove();
}, 3000);
}
// Show OTA section
function showOTA() {
const otaContainer = document.getElementById('otaContainer');
if (otaContainer && (otaContainer.style.display === 'none' || !otaContainer.style.display)) {
otaContainer.style.display = 'block';
// Attention-grabbing pulse effect
setTimeout(() => {
const otaHeader = document.querySelector('.ota-header h3');
if (otaHeader) {
otaHeader.style.animation = 'pulse 1s ease-in-out';
}
}, 100);
}
}
// Analytics tracking
function trackEvent(eventName, data = {}) {
if (typeof gtag !== 'undefined') {
gtag('event', eventName, {
'event_category': TOOL_CONFIG.category,
'event_label': TOOL_CONFIG.name,
...data
});
}
}
// ========== AI ASSISTANT FUNCTIONS ==========
// AI λͺ¨λ¬ μ΄κΈ°
function openAIModal() {
const modal = document.getElementById('aiModal');
if(modal) modal.classList.add('show');
if (aiModalState.apiKey && aiModalState.currentView === 'gemini') {
showGeminiChat();
} else {
showAISelector();
}
updateAPIKeyStatus();
}
// AI λͺ¨λ¬ λ«κΈ°
function closeAIModal() {
const modal = document.getElementById('aiModal');
if(modal) modal.classList.remove('show');
setTimeout(() => {
aiModalState.currentView = 'selector';
showAISelector();
}, 300);
}
// AI μ ν νλ©΄ νμ
function showAISelector() {
document.getElementById('aiModalTitle').textContent = 'Choose Your AI Assistant';
document.getElementById('aiSelector').style.display = 'flex';
document.getElementById('geminiChat').style.display = 'none';
document.getElementById('apiKeySetup').style.display = 'none';
aiModalState.currentView = 'selector';
}
// Gemini μ±ν
νλ©΄ νμ
function showGeminiChat() {
document.getElementById('aiModalTitle').innerHTML = 'β¨ Gemini AI Assistant';
document.getElementById('aiSelector').style.display = 'none';
document.getElementById('geminiChat').style.display = 'flex';
document.getElementById('apiKeySetup').style.display = 'none';
aiModalState.currentView = 'gemini';
const chatMessages = document.getElementById('chatMessages');
if (!chatMessages.innerHTML.trim()) {
addMessage('assistant', `Hello! I can help you with:
β’ Time calculations and conversions
β’ Work hour tracking and payroll
β’ Project timeline planning
β’ Time zone conversions
β’ Business day calculations
β’ Time management tips
What would you like to know about time calculations?`);
}
}
// API ν€ μ€μ νλ©΄ νμ
function showAPIKeySetup() {
document.getElementById('aiModalTitle').textContent = 'Setup Gemini API';
document.getElementById('aiSelector').style.display = 'none';
document.getElementById('geminiChat').style.display = 'none';
document.getElementById('apiKeySetup').style.display = 'block';
aiModalState.currentView = 'setup';
}
// AI μ ν μ²λ¦¬
function selectAI(aiType) {
switch(aiType) {
case 'chatgpt':
const toolContext = `I need help with time duration calculations using the Time Duration Calculator on WIA Pin Code platform. Current mode: ${currentMode}.`;
const chatUrl = `https://chat.openai.com/?q=${encodeURIComponent(toolContext)}`;
window.open(chatUrl, '_blank');
closeAIModal();
trackEvent('ai_selection', { ai_type: 'chatgpt' });
break;
case 'claude':
const claudeContext = `I need help with time duration calculations using the Time Duration Calculator on WIA Pin Code platform. Current mode: ${currentMode}.`;
const claudeUrl = `https://claude.ai/chat?q=${encodeURIComponent(claudeContext)}`;
window.open(claudeUrl, '_blank');
closeAIModal();
trackEvent('ai_selection', { ai_type: 'claude' });
break;
case 'gemini':
if (!aiModalState.apiKey) {
showAPIKeySetup();
} else {
showGeminiChat();
}
trackEvent('ai_selection', { ai_type: 'gemini' });
break;
}
}
// API ν€ μ μ₯
function saveGeminiApiKey() {
const apiKey = document.getElementById('geminiApiKeyInput').value.trim();
if (apiKey) {
localStorage.setItem('geminiApiKey', apiKey);
aiModalState.apiKey = apiKey;
showGeminiChat();
updateAPIKeyStatus();
} else {
alert('Please enter a valid API key');
}
}
// API ν€ μν μ
λ°μ΄νΈ
function updateAPIKeyStatus() {
const statusEl = document.getElementById('apiKeyStatus');
if (aiModalState.apiKey) {
statusEl.innerHTML = 'Change API Key';
} else {
statusEl.textContent = 'No API key set';
}
}
// μ±ν
λ©μμ§ μΆκ°
function addMessage(type, content) {
const chatMessages = document.getElementById('chatMessages');
const messageDiv = document.createElement('div');
messageDiv.className = `message ${type}`;
if (type === 'user') {
messageDiv.innerHTML = `You: ${content}`;
} else {
messageDiv.innerHTML = `β¨ Gemini:${content.replace(/\n/g, '
')}`; } chatMessages.appendChild(messageDiv); chatMessages.scrollTop = chatMessages.scrollHeight; } // Geminiμ λ©μμ§ μ μ‘ async function sendToGemini() { const input = document.getElementById('geminiInput'); const message = input.value.trim(); if (!message) return; addMessage('user', message); input.value = ''; const loadingMsg = document.createElement('div'); loadingMsg.className = 'message assistant'; loadingMsg.innerHTML = 'β¨ Gemini:
Thinking...'; loadingMsg.id = 'loading-message'; document.getElementById('chatMessages').appendChild(loadingMsg); try { const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=${aiModalState.apiKey}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ contents: [{ parts: [{ text: `Context: User is using the Time Duration Calculator on WIA Pin Code platform. Current calculation mode: ${currentMode} This tool calculates time durations between dates/times, work hours, and business days. User question: ${message}` }] }], generationConfig: { temperature: 0.7, maxOutputTokens: 1000 } }) }); const data = await response.json(); document.getElementById('loading-message').remove(); if (data.candidates && data.candidates[0] && data.candidates[0].content) { const reply = data.candidates[0].content.parts[0].text; addMessage('assistant', reply); } else { addMessage('assistant', 'Sorry, I could not generate a response. Please try again.'); } } catch (error) { document.getElementById('loading-message')?.remove(); if (error.message.includes('API key')) { addMessage('error', 'Invalid API key. Please check your API key and try again.'); showAPIKeySetup(); } else { addMessage('error', 'Failed to connect to Gemini. Please check your internet connection and try again.'); } } } // ========== EVENT LISTENERS ========== document.addEventListener('DOMContentLoaded', function() { // Initialize default date/time values const now = new Date(); const hour = now.getHours(); const minute = now.getMinutes(); // Set default datetime values document.getElementById('startDateTime').value = formatDateTimeLocal(now, 9, 0); const defaultEnd = new Date(now); defaultEnd.setHours(17, 30); document.getElementById('endDateTime').value = formatDateTimeLocal(defaultEnd, 17, 30); // Set default date values document.getElementById('startDate').value = formatDateOnly(now); const defaultEndDate = new Date(now); defaultEndDate.setDate(defaultEndDate.getDate() + 30); document.getElementById('endDate').value = formatDateOnly(defaultEndDate); // Enter key support for all inputs document.querySelectorAll('.time-input, .input-field').forEach(input => { input.addEventListener('keypress', function(e) { if (e.key === 'Enter') { calculateDuration(); } }); }); // Clear errors on input document.querySelectorAll('.time-input, .input-field').forEach(input => { input.addEventListener('input', clearErrors); }); // AI λ²νΌ μ΄λ²€νΈ document.getElementById('aiBtn').addEventListener('click', openAIModal); // λͺ¨λ¬ μΈλΆ ν΄λ¦μ λ«κΈ° document.getElementById('aiModal').addEventListener('click', function(e) { if (e.target === this) { closeAIModal(); } }); // μν° ν€ μ§μ λ° ESC ν€λ‘ λͺ¨λ¬ λ«κΈ° document.addEventListener('keydown', function(e) { if (e.key === 'Enter') { const geminiInput = document.getElementById('geminiInput'); if (document.activeElement === geminiInput) { sendToGemini(); } } if (e.key === 'Escape') { closeAIModal(); } }); // μ΄κΈ° API ν€ μν μ λ°μ΄νΈ updateAPIKeyStatus(); updateCurrentYear(); updateToolCount(); }); // ========== DYNAMIC TOOL COUNT ========== async function updateToolCount() { try { const response = await fetch('/api/tool-count.php'); const data = await response.json(); document.querySelectorAll('.dynamic-tools-count').forEach(el => { el.textContent = `${data.count}+ free productivity tools in 211 languages. No signup, no fees, just tools that work.`; }); document.querySelectorAll('.dynamic-count').forEach(el => { const prefix = el.getAttribute('data-text') || ''; const suffix = el.getAttribute('data-suffix') || ''; const icon = el.textContent.split(' ')[0] || ''; el.textContent = `${icon} ${prefix} ${data.count}+ ${suffix}`; }); } catch (error) { const fallbackCount = 333; document.querySelectorAll('.dynamic-tools-count').forEach(el => { el.textContent = `${fallbackCount}+ free productivity tools in 211 languages. No signup, no fees, just tools that work.`; }); document.querySelectorAll('.dynamic-count').forEach(el => { const prefix = el.getAttribute('data-text') || ''; const suffix = el.getAttribute('data-suffix') || ''; const icon = el.textContent.split(' ')[0] || ''; el.textContent = `${icon} ${prefix} ${fallbackCount}+ ${suffix}`; }); } } function updateCurrentYear() { const currentYear = new Date().getFullYear(); document.querySelectorAll('.current-year').forEach(el => { el.textContent = currentYear; }); } // ========== ANALYTICS ========== window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-XXXXXXXXX'); trackEvent('page_view', { tool: TOOL_CONFIG.name, category: TOOL_CONFIG.category });