/** * TXA Format Utility * Version: 1.0 (Web Optimized) */ const txaformat = { twoDigits: (n) => (n < 10 ? '0' : '') + n, shortNumber: (n) => { if (n >= 1000000) return (n / 1000000).toFixed(1) + 'M'; if (n >= 1000) return (n / 1000).toFixed(1) + 'K'; return n; }, number: (n) => new Intl.NumberFormat('vi-VN').format(n), duration: function (s) { const h = Math.floor(s / 3600); const m = Math.floor((s % 3600) / 60); const sec = Math.floor(s % 60); let str = ''; if (h > 0) str += this.twoDigits(h) + ':'; return str + this.twoDigits(m) + ':' + this.twoDigits(sec); }, fileSize: (bytes) => { if (bytes === 0) return '0 B'; const units = ['B', 'KB', 'MB', 'GB', 'TB']; const i = Math.floor(Math.log(bytes) / Math.log(1024)); return parseFloat((bytes / Math.pow(1024, i)).toFixed(2)) + ' ' + units[i]; }, dateTime: (val) => { if (!val) return ''; const d = new Date(val); if (isNaN(d.getTime())) return val; return d.toLocaleString('vi-VN'); }, relativeTime: (val) => { if (!val) return ''; const date = new Date(val); const now = new Date(); const diffMs = now.getTime() - date.getTime(); if (isNaN(date.getTime()) || diffMs < 0) return 'Vừa xong'; const diffSec = Math.floor(diffMs / 1000); if (diffSec < 60) return 'Vừa xong'; const diffMin = Math.floor(diffSec / 60); if (diffMin < 60) return `${diffMin} phút trước`; const diffHour = Math.floor(diffMin / 60); if (diffHour < 24) return `${diffHour} giờ trước`; // Quá 1 ngày (24 giờ) sẽ hiện là ngày/tháng/năm const day = date.getDate(); const month = date.getMonth() + 1; const year = date.getFullYear(); return `${day}/${month}/${year}`; } }; if (typeof window !== 'undefined') { window.txaformat = txaformat; }