关于HTML中将纪元数字转换为可读日期及Angular应用中Stripe发票Firestore数字时间戳转换的技术问询
Hey there! Let's tackle your two connected problems step by step—first fixing the root issue with Firestore timestamps, then covering direct date conversion in HTML.
1. Converting Epoch Numbers to Firestore Timestamps (The Root Fix)
The reason {{ created.toDate() | date: 'dd/MM/yyyy HH:mm' }} wasn't working is straightforward: your created field is a raw numeric value, not a Firestore Timestamp object. The toDate() method only exists on Timestamp instances, so we need to convert that number first. Here are two solid approaches:
Option 1: Convert Data in Your Angular Service (Frontend-First)
This is the most flexible fix for your existing Angular app. When fetching invoice data from Firestore, map the numeric created field to a Firestore Timestamp before passing it to your component:
// In your invoice service file import { Injectable } from '@angular/core'; import { AngularFirestore } from '@angular/fire/compat/firestore'; import { map } from 'rxjs/operators'; import firebase from 'firebase/compat/app'; @Injectable({ providedIn: 'root' }) export class InvoiceService { constructor(private firestore: AngularFirestore) {} getInvoices() { return this.firestore.collection('invoices').valueChanges().pipe( map(invoices => invoices.map(invoice => ({ ...invoice, // Convert epoch milliseconds to Firestore Timestamp created: firebase.firestore.Timestamp.fromMillis(invoice.created) })) ) ); } }
Once you implement this, your original template code {{ created.toDate() | date: 'dd/MM/yyyy HH:mm' }} will work perfectly, since created is now a proper Timestamp object.
Option 2: Use a Cloud Firestore Trigger (Backend Auto-Conversion)
If you want this conversion to happen automatically for both existing and new invoices, use a Cloud Function. This way, you don't have to modify frontend code, and all future invoices will have the correct Timestamp field:
// In your Cloud Functions index.js file const functions = require('firebase-functions'); const admin = require('firebase-admin'); admin.initializeApp(); exports.convertCreatedToTimestamp = functions.firestore .document('invoices/{invoiceId}') .onWrite(async (change, context) => { const invoiceData = change.after.data(); // Only convert if `created` is a number and not already a Timestamp if (typeof invoiceData.created === 'number' && !(invoiceData.created instanceof admin.firestore.Timestamp)) { await change.after.ref.update({ created: admin.firestore.Timestamp.fromMillis(invoiceData.created) }); } return null; });
Deploy this function, and it will automatically update any invoice document where created is a numeric epoch value.
2. Directly Convert Epoch Numbers to Readable Dates in HTML
If you can't convert the field to a Timestamp right away, you can still display the date directly using Angular's Date pipe—since it accepts numeric epoch values (in milliseconds) as input. Just use this in your template:
{{ created | date: 'dd/MM/yyyy HH:mm' }}
That's it! The pipe handles converting the epoch number to a human-readable date without needing toDate().
Bonus: Component Method for Custom Logic
If you need more control over the conversion (like handling epoch values in seconds instead of milliseconds), add a method to your component:
// In your invoice component file convertEpochToDate(epochValue: number): Date { // If your epoch is in seconds, multiply by 1000 here return new Date(epochValue); }
Then use it in the template:
{{ convertEpochToDate(created) | date: 'dd/MM/yyyy HH:mm' }}
内容的提问来源于stack exchange,提问作者Michael Cockinos

