Skip to content

Commit d5aa1db

Browse files
committed
refactor: salesforce convert date format to salesforce format
1 parent fb3919e commit d5aa1db

File tree

1 file changed

+126
-58
lines changed

1 file changed

+126
-58
lines changed

includes/Actions/Salesforce/RecordApiHelper.php

Lines changed: 126 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
use BitCode\FI\Core\Util\Common;
66
use BitCode\FI\Core\Util\HttpHelper;
77
use BitCode\FI\Log\LogHandler;
8+
use DateTime;
9+
use DateTimeImmutable;
10+
use DateTimeZone;
11+
use Throwable;
812

913
/**
1014
* Provide functionality for Record insert,upsert
@@ -38,6 +42,7 @@ public function generateReqDataFromFieldMap($data, $fieldMap)
3842
: $data[$triggerValue]
3943
);
4044
}
45+
error_log('Salesforce Final Data: ' . print_r($dataFinal, true));
4146

4247
return $dataFinal;
4348
}
@@ -279,83 +284,146 @@ public function execute($integrationDetails, $fieldValues, $fieldMap, $actions)
279284
return true;
280285
}
281286

282-
public static function convertToSalesforceFormat($inputDate)
287+
public static function convertToSalesforceFormat($input)
283288
{
284-
// First, strip any leading/trailing spaces
285-
$inputDate = trim($inputDate);
286-
287-
// Handle 2-digit year date formats (like 25/11/13 or 11/25/13)
288-
if (preg_match("/^\d{2}\/\d{2}\/\d{2}$/", $inputDate)) {
289-
// Convert DD/MM/YY or MM/DD/YY to YYYY-MM-DD
290-
$parts = explode('/', $inputDate);
291-
if (\strlen($parts[2]) == 2) {
292-
// Handling 2-digit year (assuming the year is in the 2000s)
293-
$year = '20' . $parts[2];
294-
$month = $parts[1];
295-
$day = $parts[0];
296-
$formattedDate = "{$year}-{$month}-{$day}";
297-
}
298-
// Validate and return the formatted date
299-
if (strtotime($formattedDate)) {
300-
return $formattedDate; // Return in YYYY-MM-DD format
301-
}
289+
if (!$input || !\is_string($input)) {
290+
return $input;
291+
}
302292

303-
return $inputDate;
293+
$input = trim($input);
294+
295+
// ------------------------------------------------------------
296+
// 1) Handle UNIX timestamps (10 or 13 digits)
297+
// ------------------------------------------------------------
298+
if (preg_match('/^\d{10}$/', $input)) {
299+
return gmdate('Y-m-d\TH:i:s\Z', (int) $input);
300+
}
301+
if (preg_match('/^\d{13}$/', $input)) {
302+
return gmdate('Y-m-d\TH:i:s\Z', (int) ($input / 1000));
304303
}
305304

306-
// Handle formats like DD/MM/YYYY or MM/DD/YYYY
307-
if (preg_match("/^\d{2}\/\d{2}\/\d{4}$/", $inputDate)) {
308-
// Convert DD/MM/YYYY or MM/DD/YYYY to YYYY-MM-DD
309-
$parts = explode('/', $inputDate);
310-
$year = $parts[2];
311-
$month = $parts[1];
312-
$day = $parts[0];
313-
$formattedDate = "{$year}-{$month}-{$day}";
314-
// Validate and return the formatted date
315-
if (strtotime($formattedDate)) {
316-
return $formattedDate; // Return in YYYY-MM-DD format
305+
// ------------------------------------------------------------
306+
// 2) Natural-language dates ("today", "tomorrow", "next Monday", etc.)
307+
// ------------------------------------------------------------
308+
if (preg_match('/^[a-zA-Z ]+$/', $input) || str_contains($input, 'ago')) {
309+
$ts = strtotime($input);
310+
if ($ts) {
311+
return gmdate('Y-m-d', $ts);
317312
}
313+
}
318314

319-
return $inputDate;
315+
// ------------------------------------------------------------
316+
// 3) Clean ordinals: 1st, 2nd, 3rd, 21st, 31st...
317+
// ------------------------------------------------------------
318+
$clean = preg_replace('/\b(\d+)(st|nd|rd|th)\b/i', '$1', $input);
319+
320+
// ------------------------------------------------------------
321+
// 4) Japanese/Chinese/Korean locale replacements
322+
// ------------------------------------------------------------
323+
$clean = str_replace(
324+
['', '', '', '', '', ''],
325+
['-', '-', '', '-', '-', ''],
326+
$clean
327+
);
328+
329+
// ------------------------------------------------------------
330+
// 5) Week-based formats (2025-W05 or 2025-W05-6)
331+
// ------------------------------------------------------------
332+
if (preg_match('/^(\d{4})-?W(\d{2})(?:-?(\d))?$/i', $clean, $m)) {
333+
$year = $m[1];
334+
$week = $m[2];
335+
$day = $m[3] ?? 1;
336+
337+
try {
338+
$dt = new DateTime("{$year}-W{$week}-{$day}", new DateTimeZone('UTC'));
339+
340+
return $dt->format('Y-m-d');
341+
} catch (Throwable $e) {
342+
}
320343
}
321344

322-
// Handle formats like YYYY-MM-DD
323-
if (preg_match("/^\d{4}-\d{2}-\d{2}$/", $inputDate)) {
324-
// It's already in the correct format (YYYY-MM-DD)
325-
return $inputDate;
345+
// ------------------------------------------------------------
346+
// 6) Quarter formats (Q1 2025, 2025 Q1, 1st Quarter 2025)
347+
// ------------------------------------------------------------
348+
if (preg_match('/(Q[1-4]|[1-4]st Quarter)\s*[, ]*\s*(\d{4})/i', $clean, $m)) {
349+
$q = preg_replace('/\D/', '', $m[1]); // Extract 1–4
350+
$year = $m[2];
351+
$month = (($q - 1) * 3) + 1;
352+
353+
return "{$year}-" . str_pad($month, 2, '0', STR_PAD_LEFT) . '-01';
326354
}
327355

328-
// Handle formats like YYYY/MM/DD
329-
if (preg_match("/^\d{4}\/\d{2}\/\d{2}$/", $inputDate)) {
330-
// Convert YYYY/MM/DD to YYYY-MM-DD
331-
$formattedDate = str_replace('/', '-', $inputDate);
332-
// Validate and return the formatted date
333-
if (strtotime($formattedDate)) {
334-
return $formattedDate; // Return in YYYY-MM-DD format
356+
// ------------------------------------------------------------
357+
// 7) Compact numeric formats (01022025, 20250201, 250201, 010225)
358+
// ------------------------------------------------------------
359+
if (preg_match('/^\d{8}$/', $clean)) {
360+
// YYYYMMDD or DDMMYYYY or MMDDYYYY → try multiple interpretations
361+
$candidates = [
362+
substr($clean, 0, 4) . '-' . substr($clean, 4, 2) . '-' . substr($clean, 6, 2), // YMD
363+
substr($clean, 4, 4) . '-' . substr($clean, 2, 2) . '-' . substr($clean, 0, 2), // DMY
364+
];
365+
foreach ($candidates as $c) {
366+
if (strtotime($c)) {
367+
return $c;
368+
}
335369
}
370+
}
336371

337-
return $inputDate;
372+
if (preg_match('/^\d{6}$/', $clean)) {
373+
// DDMMYY / YYMMDD / MMDDYY
374+
$yy = substr($clean, -2);
375+
$year = $yy > 70 ? "19{$yy}" : "20{$yy}";
376+
377+
$dm = substr($clean, 0, 2) . '-' . substr($clean, 2, 2) . '-' . $year;
378+
$md = substr($clean, 2, 2) . '-' . substr($clean, 0, 2) . '-' . $year;
379+
380+
foreach ([$dm, $md] as $c) {
381+
$ts = strtotime($c);
382+
if ($ts) {
383+
return gmdate('Y-m-d', $ts);
384+
}
385+
}
338386
}
339387

340-
// Handle date formats with time: YYYY-MM-DD HH:MM:SS
341-
if (preg_match("/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}(:\d{2}(\.\d{1,3})?)?$/", $inputDate)) {
342-
// It's a datetime with or without milliseconds
343-
$date = strtotime($inputDate);
344-
if ($date === false) {
345-
return $inputDate;
388+
// ------------------------------------------------------------
389+
// 8) Try direct DateTime parsing for most formats
390+
// ------------------------------------------------------------
391+
$tryParse = function ($value) {
392+
try {
393+
return new DateTimeImmutable($value);
394+
} catch (Throwable $e) {
395+
return;
396+
}
397+
};
398+
399+
$dt = $tryParse($clean);
400+
401+
if ($dt instanceof DateTimeImmutable) {
402+
// Detect if datetime or pure date
403+
if (preg_match('/\d{1,2}:\d/', $clean)) {
404+
return $dt->setTimezone(new DateTimeZone('UTC'))
405+
->format('Y-m-d\TH:i:s\Z');
346406
}
347407

348-
// Convert to Salesforce ISO 8601 datetime with UTC (Z)
349-
return gmdate("Y-m-d\TH:i:s\Z", $date); // Convert to UTC and add Z
408+
return $dt->format('Y-m-d');
350409
}
351410

352-
// Handle datetime formats with ISO 8601 style (e.g., 2025-09-20T10:30:00Z or with milliseconds)
353-
if (preg_match("/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(Z|(\.\d{1,3})?)?$/", $inputDate)) {
354-
// It's already in ISO 8601 format, return as is
355-
return strtoupper($inputDate); // Normalize to uppercase 'Z' if needed
411+
// ------------------------------------------------------------
412+
// 9) Last fallback using strtotime()
413+
// ------------------------------------------------------------
414+
$ts = strtotime($clean);
415+
if ($ts) {
416+
// Detect datetime or date-only
417+
if (preg_match('/\d{1,2}:\d/', $clean)) {
418+
return gmdate('Y-m-d\TH:i:s\Z', $ts);
419+
}
420+
421+
return gmdate('Y-m-d', $ts);
356422
}
357423

358-
// If input contains no recognizable date/time format, return an error
359-
return $inputDate;
424+
// ------------------------------------------------------------
425+
// 10) No match → return original
426+
// ------------------------------------------------------------
427+
return $input;
360428
}
361429
}

0 commit comments

Comments
 (0)