Time-of-Day Behavioral Tagger
Temporal User Segmentation
Automatically segments visitors based on time-of-day patterns, business hours, and behavioral timing to enable time-sensitive personalization and targeted messaging campaigns.
Key Features
Script Overview
What It Does
This script analyzes the visitor's local time to create behavioral segments based on when they visit your site. It detects timezone, classifies visits into business hours, weekend/weekday patterns, and pushes detailed temporal data to GTM for personalized messaging and analytics.
Use Case
Great for businesses with time-sensitive offers or different messaging for business hours. Perfect for B2B companies that want to tailor messaging based on when prospects are most likely to be working vs browsing personally.
Key Benefits
- •Time-based visitor segmentation for personalization
- •Business hours vs after-hours visitor classification
- •Weekend and weekday behavioral analysis
- •Timezone-aware visitor insights
- •Enhanced behavioral targeting capabilities
- •Temporal conversion pattern analysis
JavaScript Code
<script>
(function() {
'use strict';
// Time-of-Day Behavioral Tagger Script
// Version: 1.0
// Description: Segments visitors by time patterns and behavior
// Last Updated: 2025-09-09
// Configuration
var config = {
// Business hours configuration (24-hour format)
businessHours: {
start: 9, // 9 AM
end: 17, // 5 PM
timezone: 'auto' // 'auto' to detect, or specify like 'America/New_York'
},
// Weekend configuration
weekendDays: [0, 6], // Sunday = 0, Saturday = 6
// Time segments configuration
timeSegments: {
'early-morning': { start: 5, end: 9 }, // 5 AM - 9 AM
'morning': { start: 9, end: 12 }, // 9 AM - 12 PM
'afternoon': { start: 12, end: 17 }, // 12 PM - 5 PM
'evening': { start: 17, end: 21 }, // 5 PM - 9 PM
'night': { start: 21, end: 24 }, // 9 PM - 12 AM
'late-night': { start: 0, end: 5 } // 12 AM - 5 AM
},
// DataLayer event configuration
events: {
timeSegment: 'time_behavioral_tag',
sessionAnalysis: 'session_time_analysis'
},
// Storage for session analysis
storageKey: 'time_behavioral_data',
// Debug mode
debug: false
};
// Utility functions
function debugLog(message, data) {
if (config.debug) {
console.log('[Time Tagger] ' + message, data || '');
}
}
function getCurrentTimeInfo() {
var now = new Date();
var timeInfo = {
timestamp: now.getTime(),
iso: now.toISOString(),
// Local time information
localHour: now.getHours(),
localMinute: now.getMinutes(),
localDay: now.getDay(), // 0 = Sunday, 6 = Saturday
localDate: now.getDate(),
localMonth: now.getMonth() + 1,
localYear: now.getFullYear(),
// Timezone information
timezoneOffset: now.getTimezoneOffset(),
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone || 'Unknown'
};
return timeInfo;
}
function getTimeSegment(hour) {
for (var segment in config.timeSegments) {
var segmentConfig = config.timeSegments[segment];
// Handle segments that cross midnight
if (segmentConfig.start > segmentConfig.end) {
if (hour >= segmentConfig.start || hour < segmentConfig.end) {
return segment;
}
} else {
if (hour >= segmentConfig.start && hour < segmentConfig.end) {
return segment;
}
}
}
return 'unknown';
}
function isBusinessHours(hour, day) {
// Check if it's a weekend
if (config.weekendDays.includes(day)) {
return false;
}
// Check if within business hours
return hour >= config.businessHours.start && hour < config.businessHours.end;
}
function isWeekend(day) {
return config.weekendDays.includes(day);
}
function getBehavioralClassification(timeInfo) {
var classification = {
timeSegment: getTimeSegment(timeInfo.localHour),
isBusinessHours: isBusinessHours(timeInfo.localHour, timeInfo.localDay),
isWeekend: isWeekend(timeInfo.localDay),
dayType: isWeekend(timeInfo.localDay) ? 'weekend' : 'weekday',
hourCategory: timeInfo.localHour < 12 ? 'am' : 'pm'
};
// Advanced behavioral insights
if (classification.isBusinessHours && !classification.isWeekend) {
classification.behaviorType = 'business-browsing';
classification.intent = 'professional';
} else if (classification.isWeekend) {
classification.behaviorType = 'leisure-browsing';
classification.intent = 'personal';
} else if (!classification.isBusinessHours && !classification.isWeekend) {
classification.behaviorType = 'after-hours-browsing';
classification.intent = 'mixed';
} else {
classification.behaviorType = 'general-browsing';
classification.intent = 'unknown';
}
return classification;
}
function getSessionTimePattern() {
try {
var stored = sessionStorage.getItem(config.storageKey + '_session');
if (stored) {
return JSON.parse(stored);
}
} catch (e) {
debugLog('Error reading session time data:', e);
}
return null;
}
function updateSessionTimePattern(timeInfo, classification) {
try {
var sessionData = getSessionTimePattern() || {
sessionStart: timeInfo.timestamp,
visitCount: 0,
timeSegments: [],
behaviorTypes: []
};
sessionData.visitCount += 1;
sessionData.lastVisit = timeInfo.timestamp;
sessionData.sessionDuration = timeInfo.timestamp - sessionData.sessionStart;
// Track unique time segments in this session
if (!sessionData.timeSegments.includes(classification.timeSegment)) {
sessionData.timeSegments.push(classification.timeSegment);
}
// Track unique behavior types in this session
if (!sessionData.behaviorTypes.includes(classification.behaviorType)) {
sessionData.behaviorTypes.push(classification.behaviorType);
}
sessionStorage.setItem(config.storageKey + '_session', JSON.stringify(sessionData));
return sessionData;
} catch (e) {
debugLog('Error updating session time data:', e);
return null;
}
}
function getHistoricalTimePattern() {
try {
var stored = localStorage.getItem(config.storageKey);
if (stored) {
var data = JSON.parse(stored);
// Clean old data (keep only last 30 days)
var thirtyDaysAgo = Date.now() - (30 * 24 * 60 * 60 * 1000);
if (data.visits) {
data.visits = data.visits.filter(function(visit) {
return visit.timestamp > thirtyDaysAgo;
});
}
return data;
}
} catch (e) {
debugLog('Error reading historical time data:', e);
}
return {
visits: [],
patterns: {},
preferences: {}
};
}
function updateHistoricalTimePattern(timeInfo, classification) {
try {
var historical = getHistoricalTimePattern();
// Add current visit
historical.visits.push({
timestamp: timeInfo.timestamp,
timeSegment: classification.timeSegment,
behaviorType: classification.behaviorType,
isBusinessHours: classification.isBusinessHours,
isWeekend: classification.isWeekend
});
// Update patterns
historical.patterns.mostCommonTimeSegment = getMostCommonValue(
historical.visits.map(function(v) { return v.timeSegment; })
);
historical.patterns.mostCommonBehaviorType = getMostCommonValue(
historical.visits.map(function(v) { return v.behaviorType; })
);
// Calculate preferences
var businessHoursVisits = historical.visits.filter(function(v) { return v.isBusinessHours; });
var weekendVisits = historical.visits.filter(function(v) { return v.isWeekend; });
historical.preferences.businessHoursFrequency = businessHoursVisits.length / historical.visits.length;
historical.preferences.weekendFrequency = weekendVisits.length / historical.visits.length;
historical.preferences.totalVisits = historical.visits.length;
localStorage.setItem(config.storageKey, JSON.stringify(historical));
return historical;
} catch (e) {
debugLog('Error updating historical time data:', e);
return null;
}
}
function getMostCommonValue(array) {
var counts = {};
var mostCommon = array[0];
var maxCount = 1;
array.forEach(function(item) {
counts[item] = (counts[item] || 0) + 1;
if (counts[item] > maxCount) {
mostCommon = item;
maxCount = counts[item];
}
});
return mostCommon;
}
function pushToDataLayer(timeInfo, classification, sessionData, historicalData) {
window.dataLayer = window.dataLayer || [];
// Main time behavioral event
var eventData = {
event: config.events.timeSegment,
// Current time information
time_segment: classification.timeSegment,
is_business_hours: classification.isBusinessHours,
is_weekend: classification.isWeekend,
day_type: classification.dayType,
behavior_type: classification.behaviorType,
intent_type: classification.intent,
// Time details
local_hour: timeInfo.localHour,
local_day: timeInfo.localDay,
timezone: timeInfo.timezone,
// Session information
session_visit_count: sessionData ? sessionData.visitCount : 1,
session_time_segments: sessionData ? sessionData.timeSegments : [classification.timeSegment],
// Historical patterns (if available)
visitor_time_preference: historicalData ? historicalData.patterns.mostCommonTimeSegment : classification.timeSegment,
visitor_behavior_preference: historicalData ? historicalData.patterns.mostCommonBehaviorType : classification.behaviorType,
business_hours_frequency: historicalData ? Math.round(historicalData.preferences.businessHoursFrequency * 100) : null,
weekend_frequency: historicalData ? Math.round(historicalData.preferences.weekendFrequency * 100) : null
};
window.dataLayer.push(eventData);
// Session analysis event (if multiple visits in session)
if (sessionData && sessionData.visitCount > 1) {
window.dataLayer.push({
event: config.events.sessionAnalysis,
session_duration_minutes: Math.round(sessionData.sessionDuration / (1000 * 60)),
session_time_segments_count: sessionData.timeSegments.length,
session_behavior_diversity: sessionData.behaviorTypes.length
});
}
debugLog('Time behavioral data pushed to dataLayer:', eventData);
}
// Main execution
function initTimeBehavioralTagger() {
debugLog('Initializing Time Behavioral Tagger');
var timeInfo = getCurrentTimeInfo();
var classification = getBehavioralClassification(timeInfo);
debugLog('Time classification:', classification);
// Update session and historical data
var sessionData = updateSessionTimePattern(timeInfo, classification);
var historicalData = updateHistoricalTimePattern(timeInfo, classification);
// Push to dataLayer
pushToDataLayer(timeInfo, classification, sessionData, historicalData);
}
// Initialize when DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initTimeBehavioralTagger);
} else {
initTimeBehavioralTagger();
}
// Expose utility functions
window.timeBehavioralTagger = {
getCurrentClassification: function() {
var timeInfo = getCurrentTimeInfo();
return getBehavioralClassification(timeInfo);
},
getSessionData: function() {
return getSessionTimePattern();
},
getHistoricalData: function() {
return getHistoricalTimePattern();
},
clearHistoricalData: function() {
localStorage.removeItem(config.storageKey);
debugLog('Historical time data cleared');
},
refreshAnalysis: function() {
initTimeBehavioralTagger();
}
};
})();
</script>
💡 Pro Tip: Copy the entire code block above and paste it directly into a GTM Custom HTML tag. The script is self-contained and ready to use immediately.