The dates are not wrong. Stripe is stamping the moment the transaction happened in UTC, while your bank CSV is stamping the day cash posted in local time. When a payment lands near midnight, those become different calendar days. When Stripe also batches several transactions into one payout, the row-by-row comparison fails even faster.

That is why you can see a Stripe charge on May 31, a bank line on June 1, and still be looking at the same movement of money. The mismatch is usually not missing cash. It is a mix of timezone conversion, payout timing, and the fact that Stripe charge rows are not the same thing as bank statement rows.

The first check is what kind of date mismatch you actually have

Before you change formats in Excel, identify which case you have. The same-looking mismatch can come from several different causes, and only some of them are pure UTC problems.

What you see on screenHow Stripe stores itHow the other file stores itWhat the result actually means
2026-05-31 23:47:18 UTC in Stripe and 2026-06-01 in the bank CSVCharge created late in the UTC dayLocal bank posting lands after midnight in the account timezoneSame event can appear one day later after timezone conversion
2026-05-01 00:12:44 UTC in Stripe and 2026-04-30 in the bank CSVCharge created just after midnight UTCLocal timezone west of UTC still shows the previous eveningSame event can appear one day earlier after conversion
2026-05-15 in a Stripe payout export and 2026-05-17 in the bank CSVFunds became available or payout was created on one dateBank posted the deposit two business days laterThis is payout timing, not a timezone error
01/05/2026 in the bank CSV and 2026-05-01 09:14:02 UTC in StripeISO-style timestamp with timeText date with ambiguous day and month orderYou cannot compare until the bank date is normalized
Twelve Stripe rows for sales, refunds, and fees versus one bank row for the net depositCharge-level activityDeposit-level cash eventThis is the wrong comparison level, even if the dates were identical

Only the first two rows are true timezone shifts. The third is settlement timing. The fourth is a text-date import problem. The fifth is the one that wastes the most time because it looks like a date issue when it is really a file-structure issue.

Which Stripe date are you actually looking at

Stripe exports do not use one universal "transaction date." They expose several dates that describe different moments in the payout lifecycle. If you compare the wrong one to the bank statement, you create a mismatch before the spreadsheet does anything wrong.

Stripe fieldWhat it representsWhat you should use it for
createdWhen the balance transaction was created in StripeMatching transaction history, not final bank posting
charge_createdWhen the original charge happenedMatching sales or order records, not bank deposits
available_onWhen the net funds become available in the Stripe balanceExplaining settlement timing inside Stripe
automatic_payout_effective_atWhen Stripe expects the payout to arrive in the bankMatching a payout export to a bank deposit
Bank receipt dateWhen the bank says the cash actually postedFinal cash reconciliation

This is the part many posts skip. A bank statement line is a cash event. A Stripe charge export is a transaction event. A payout reconciliation export sits between them. If you export a Stripe transactions CSV, take the created column, and compare it directly to the bank statement date, you are comparing the time the charge entered Stripe to the day cash reached the bank. Those are different events even before you account for UTC.

That is why the clean order is:

  1. Match the bank deposit to the Stripe payout.
  2. Match the payout contents to the underlying Stripe transactions.
  3. Match those transactions to orders, invoices, or ledger lines if you need transaction-level proof.

If you skip the middle layer, the timezone problem looks bigger than it is.

Convert the Stripe timestamp before you compare anything

Once you know you are looking at the correct Stripe-side date field, convert it into the same date logic as the bank file. Do not start with formatting. First find out whether Excel imported the value as a real date-time or as text.

Use =TYPE(A2) on the Stripe date cell.

  • 1 means Excel sees a numeric date-time serial.
  • 2 means Excel sees text and you need to parse it before any comparison will work.

If the Stripe value in A2 is text in a pattern like 2026-05-01 23:47:18 UTC, build the UTC date-time explicitly:

Formula
=DATE(LEFT(A2,4),MID(A2,6,2),MID(A2,9,2))+TIME(MID(A2,12,2),MID(A2,15,2),MID(A2,18,2))

That gives you the UTC timestamp as an Excel date-time value. Then convert it to local time by applying the account offset. If your accounting view is UTC-4, subtract four hours:

Formula
=DATE(LEFT(A2,4),MID(A2,6,2),MID(A2,9,2))+TIME(MID(A2,12,2),MID(A2,15,2),MID(A2,18,2))-TIME(4,0,0)

If your local reporting timezone is UTC+2, add two hours instead:

Formula
=DATE(LEFT(A2,4),MID(A2,6,2),MID(A2,9,2))+TIME(MID(A2,12,2),MID(A2,15,2),MID(A2,18,2))+TIME(2,0,0)

Once the local timestamp is correct, strip it down to the calendar date if the bank CSV only gives you a date:

Formula
=INT(B2)

Format that result as a date. Now you are comparing the local day implied by the Stripe timestamp, not the raw UTC day.

If the Stripe date is already a real Excel date-time in A2, do not parse it again. Apply the offset directly:

Formula
=A2-TIME(4,0,0)

The bank file needs the same level of care. If the bank CSV imported 01/05/2026 as text, you need to decide whether the source means day-month-year or month-day-year before you convert it.

If the bank uses dd/mm/yyyy:

Formula
=DATE(RIGHT(C2,4),MID(C2,4,2),LEFT(C2,2))

If the bank uses mm/dd/yyyy:

Formula
=DATE(RIGHT(C2,4),LEFT(C2,2),MID(C2,4,2))

Do not reach for DATEVALUE until you know which format the bank exported. A value like 01/05/2026 is not diagnostic by itself. It could be January 5 or May 1 depending on the source system and your Excel locale.

One warning matters more than most spreadsheet guides admit: a fixed -TIME(4,0,0) or -TIME(5,0,0) offset is only safe if the date range stays inside one daylight-saving period. If the export crosses the DST change, one offset can fix half the file and break the other half. In that case, split the file by period or use a Stripe report that already exposes the account-timezone column and keep the _utc version only for audit reference.

Match the payout to the bank before you touch individual charges

Once the timestamps are normalized, the next decision is matching level. If the bank CSV contains a single net deposit and the Stripe file contains individual charges, refunds, and fees, you still do not have a row-by-row match. You have a one-to-many relationship.

The bank line should be matched to a Stripe payout report first. Then the transactions inside that payout explain the amount.

StepFile you useWhat you are proving
1Bank statement CSVWhat amount hit the bank, on what posting date
2Stripe payout or payout reconciliation exportWhich payout produced that deposit
3Itemized rows inside that payoutWhich charges, refunds, disputes, and fees make up the net amount
4Orders, invoices, or ledger exportWhether the underlying activity is recorded correctly elsewhere

Suppose your bank CSV shows this line:

DateDescriptionAmount
2026-06-01STRIPE PAYOUT4,820.25

Your Stripe charge export might show thirty-seven rows created across 2026-05-31 21:00:00 UTC through 2026-06-01 03:00:00 UTC. If you compare those charge dates directly to the June 1 bank line, you will conclude that many rows are "off by one day." Some are. But the more important truth is that none of those rows are supposed to match the bank line individually. They belong to a payout batch.

The right proof looks like this:

  • The Stripe payout export shows a net payout of 4,820.25.
  • The payout field that represents expected bank arrival aligns with the bank posting window.
  • The itemized transactions inside that payout add up to the same net amount after fees, refunds, and disputes.

At that point, the date issue shrinks to its real size. It is a normalization step, not the entire reconciliation.

If you need the payout side laid out in more depth, matching a Stripe payout CSV to your bank statement and matching a bank statement to Stripe payouts when dates differ cover the deposit workflow from the other direction.

The edge cases that still create false mismatches after conversion

Getting Stripe into local time solves the first layer. It does not solve every layer. Several cases still create apparent date breaks even after the timezone math is correct.

Month-end filtering

This one catches competent teams because the spreadsheet looks clean. You export the bank CSV for May. Then you export Stripe for May in UTC. Late-evening local transactions from May 31 can appear as June 1 in Stripe, which means they fall outside the Stripe filter even though they belong in your local May close. Pull a one-day buffer on both sides of the Stripe period, convert to local date, then filter the converted date column back to the month you are closing.

Weekend and holiday posting

A payout can be effective on Friday and still reach the bank on Monday. That is not a broken date field. It is bank processing. If the payout amount and reference pattern line up, treat the date gap as settlement timing unless the cash is still missing after the normal banking window.

Refunds and disputes arriving later

The original charge might sit in one payout, while the refund or dispute hits a later one. When someone tries to reconcile the bank against charge creation dates alone, those later reductions look like unexplained mismatches. They are not unexplained. They belong to a later payout batch and need to be traced there.

Mixed timezone columns

Some Stripe exports can show both local-time and _utc versions of the same field. If you build formulas against one column this month and the other column next month, the workbook will produce inconsistencies that look like source-data errors. Choose one standard and stick to it for the entire reconciliation.

Copy-paste damage

If someone pastes Stripe rows into a sheet instead of importing the CSV, Excel can silently strip the timezone context, convert timestamps to local display values, or store them as text. When the formula starts failing only after paste, the source file may be fine and the worksheet copy is what changed.

When the spreadsheet work becomes the real problem

This mismatch is manageable when you are tracing one payout. It becomes expensive when every month requires the same cleanup: parse the Stripe timestamp, convert it to local time, buffer the period, split payout dates from charge dates, then explain why one deposit contains dozens of underlying rows.

The standard you need is not "every Stripe date equals the bank date." The standard is that every bank deposit is tied to the right Stripe payout, every payout is explained by the transactions inside it, and every remaining date gap is classified as either timezone conversion, payout timing, or a real exception that needs correction.